iOS How to create undefined UIControl in custom UITableViewCell

628 views Asked by At

I'm trying to write a prototype UITableViewCell with title and undefined UIControl that we are setting in cellForRowAtIndexPath:

Now I have implementation for cell:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self.contentView addSubview:self.titleLabel];
        [self.contentView addSubview:self.control];
    }
    return self;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        [_titleLabel setBackgroundColor:[UIColor clearColor]];
        _titleLabel.numberOfLines = 2;
        [_titleLabel setFont:[UIFont fontWithName:@"Georgia-Italic" size:15]];
        [_titleLabel setTextColor:RGBColor(51, 102, 153)];
        [_titleLabel setTextColor:[UIColor darkGrayColor]];
    }
    return _titleLabel;
}

- (UIControl *)control{
    if (!_control) {
        _control = [[UIControl alloc] init];
        [_control setBackgroundColor:[UIColor whiteColor]];
    }
    return _control;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    CGRect contentRect = [[self contentView] bounds];
    self.titleLabel.frame = CGRectMake(10, 5, 85, contentRect.size.height-10);
    self.control.frame = CGRectMake(100, 5, contentRect.size.width-105, contentRect.size.height-10);
    [self.contentView bringSubviewToFront:self.control];
    [self bringSubviewToFront: self.control];
}

And implemented cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CellAddOrder";

    ICControlCell *cell = (ICControlCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[ICControlCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
        [cell setAccessoryType:UITableViewCellAccessoryNone];
        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    }

    NSObject *cellContent = [self.cellList objectAtIndex:indexPath.row];
    cell.titleLabel.text = ICLocalized([cellContent valueForKey:@"name"]);

    switch ([[cellContent valueForKey:@"control"] intValue]) {
        case 0: {
            UITextField *textField = [[UITextField alloc] init];
            textField.placeholder = ICLocalized([[cellContent valueForKey:@"name"] stringByAppendingString:@"_placeholder"]);
            textField.delegate = self;
            textField.returnKeyType = UIReturnKeyNext;
            textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
            textField.autocorrectionType = UITextAutocorrectionTypeNo;
            textField.text = [cellContent valueForKey:@"data"];
            textField.tag = indexPath.row;
            cell.control =  textField;
        }
            break;

        case 1:
        case 2:
        case 3: {
            UISwitch *switchControl = [[UISwitch alloc] init];
            [switchControl setOn:[[cellContent valueForKey:@"data"] boolValue]];
            [switchControl addTarget:self
                              action:@selector(switchStateChanged:)
                    forControlEvents:UIControlEventValueChanged];
            switchControl.tag = indexPath.row;
            cell.control = switchControl;
        }
            break;
        default:
            break;
    }
    return cell;
}

But when I'm trying to test that controller controls for cell are not displaying, just title labels.. How can I handle that problem? Please help me

2

There are 2 answers

0
Traze On BEST ANSWER

Doc says:

You cannot use the UIControl class directly to instantiate controls.

So, you can just declare the UIControl variable the cell prototype class but set it to nil there. All the control related operations should be done from inside the delegate, because that is the place where you exactly know which class to use. So,

Don't initialize control in cell class snippet from 'control' property:

- (UIControl *)control{
    return _control;
}

Cell's constructor should also not call addSubview for control. So,

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self.contentView addSubview:self.titleLabel];
    }
    return self;
}

Add background color setting in cell's layoutSubviews here:

- (void)layoutSubviews {
...
    if (cell.control) {
        [cell.control setBackgroundColor:[UIColor whiteColor]];

        self.control.frame = CGRectMake(100, 5, contentRect.size.width-105, contentRect.size.height-10);
        [self.contentView bringSubviewToFront:self.control];
        [self bringSubviewToFront: self.control];
    }
}

Add subview in the delegate's cellforrow method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
    cell.control =  textField;
    [cell.contentView addSubview:cell.control];
...
}
0
ManiaChamp On

you should use different cell identifiers for different items for example if you have UITextField and UISwitch then you should use two identifiers because you are reusing the cell.So it should be the same type of cell to be reused.