简体   繁体   中英

iOS Auto Layout Dynamic Button Placement

I have a prototype cell with two stacked labels followed by a view that contains up to three buttons. It is possible for 0, 1, 2 or 3 buttons to be visible for any given cell (based on web xml file). I would like the layout to be as follows (X represents buttons)

3 Buttons

  |       |                   
  | X X X |         
  |       |

2 Buttons

  |       |                   
  | X   X |         
  |       |

1 Button

  |       |                   
  |   X   |         
  |       |

My table cell code sets the frame of each button depending on the total number of buttons in the cell. However the frame does seem to work until the cell is loaded for the second time (ie scroll so the cell is out of range and then back to it). Last time this occurred it was due to layout constraints. Question is, how do i set up the constraints in storyboard to allow for each button to be in on of many locations? Currently each button is pinned to top, bottom and leading edge of the button view. I know the leading edge constraint is causing the issue, but not sure what to use instead as the storyboard forces it. Or is there something I can do in my cellForRowAtIndexPath method? Here is relevant code from that method

    static NSString *CellIdentifier = @"localdiningTableCell";

        mhgiLocalDiningCell *diningcell = (mhgiLocalDiningCell*)[tableView
                                           dequeueReusableCellWithIdentifier:CellIdentifier];
        if (diningcell == nil) {
            diningcell = [[mhgiLocalDiningCell alloc]
                          initWithStyle:UITableViewCellStyleDefault
                          reuseIdentifier:CellIdentifier];
        }

        mhgiDiningXmlObject *object = [self.xmlParser.allItems objectAtIndex:[indexPath row]];

        CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);

        CGSize labelSize = [[object Name] sizeWithFont:diningcell.nameLabel.font constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
        CGRect frame = CGRectMake (10, 10, 280.0f, labelSize.height);
        diningcell.nameLabel.frame = frame;
        diningcell.nameLabel.lineBreakMode = NSLineBreakByWordWrapping;
        diningcell.nameLabel.numberOfLines = 0;
        diningcell.nameLabel.text= [object Name];
        CGFloat nextYVal = diningcell.nameLabel.frame.origin.y + diningcell.nameLabel.frame.size.height + 10.0f;



        NSString *descrText = @"";
        if (![[object Type] isEqualToString:@""]){
            descrText = [descrText stringByAppendingString:[object Type]];
            descrText = [descrText stringByAppendingString:@"\n"];
        }
        descrText = [descrText stringByAppendingString:[NSString stringWithFormat:@"%@, %@, %@", [object Street], [object City], [object State]]];
        descrText = [descrText stringByAppendingString:@"\n"];
        descrText = [descrText stringByAppendingString:[NSString stringWithFormat:@"%@ miles from the hotel", [object Distance]]];




        labelSize = [descrText sizeWithFont:diningcell.typeLabel.font constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
        frame = CGRectMake (10, nextYVal, 280.0f, labelSize.height);
        diningcell.typeLabel.frame = frame;
        diningcell.typeLabel.lineBreakMode = NSLineBreakByWordWrapping;
        diningcell.typeLabel.numberOfLines = 0;
        diningcell.typeLabel.text = descrText;
        nextYVal += diningcell.typeLabel.frame.origin.y + diningcell.typeLabel.frame.size.height + 10.0f;


        diningcell.ussite= [object UrbanSpoon];
        diningcell.website= [object Website];
        diningcell.dirsite= [object Maps];

        NSMutableArray* buttons = [[NSMutableArray alloc] init];
        [buttons removeAllObjects];


        if ([[object Website] isEqualToString:@""]){
            [diningcell.websiteButton setHidden:TRUE];
        }
        else
        {
            [diningcell.websiteButton setHidden:FALSE];
            [buttons addObject:diningcell.websiteButton];
        }



        if ([[object UrbanSpoon] isEqualToString:@""]){
            [diningcell.usButton setHidden:TRUE];
        }
        else
        {
            [diningcell.usButton setHidden:FALSE];
            [buttons addObject:diningcell.usButton];
        }

        if ([[object Maps] isEqualToString:@""]){
            [diningcell.dirButton setHidden:TRUE];
        }
        else
        {
            [diningcell.dirButton setHidden:FALSE];
            [buttons addObject:diningcell.dirButton];
        }




        if (buttons.count == 1){
            [[buttons objectAtIndex:0] setCenter:CGPointMake(150.0f, 25.0f)];

        }
        else if (buttons.count == 2){
            [[buttons objectAtIndex:0] setCenter:CGPointMake(75.0f, 25.0f)];

            [[buttons objectAtIndex:1] setCenter:CGPointMake(225.0f, 25.0f)];
        }
        else if (buttons.count == 3){
            [[buttons objectAtIndex:0] setCenter:CGPointMake(75.0f, 25.0f)];

            [[buttons objectAtIndex:1] setCenter:CGPointMake(150.0f, 25.0f)];

            [[buttons objectAtIndex:2] setCenter:CGPointMake(225.0f, 25.0f)];
        }

        return diningcell;

UPDATE I created a custom view to try and over come the layout issues. The view just houses four buttons and places them on the layoutviews method. I added a view of the custom class to my prototype cell and the layout seems to work. However when I change directions in the scrollveiw (ie down then up, up then down) some of the cells get misaligned. See image below.

Image

I'd use different prototypes for the three cell types and set the alignment up in the storyboard. You'd end up with very little code required. Just dequeue a cell of the appropriate type in cellForRowAtIndexPath: and set it up - no need to manipulate the frames directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM