开发者

UIPickerView with Multiline UILabel

I'm currently working on a program that populates a picker view dynamically from my Core Data set up. I have everything working data-wise but the problem i'm running into now is formatting on my labels.

The picker is presented with it's own toolbar in an acti开发者_StackOverflow社区onsheet with a button on the right side of the toolbar. It's initial state is with 2 dials visible. when the button is pressed it changes to 3 dials.

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    UILabel *pickerLabel = (UILabel *)view;

    CGSize limitSize = CGSizeMake(100.0f, 45.0f);
    CGSize textSize;
    CGRect labelRect;
    NSString *title = @"";


    switch (numberOfComponents){
        case 2:
        {
            ...gets strings from fetched data (varying length from 4 to 20+)
                    title = someString
        }
        case 3:
        {
            ...same as above but for the second set of data.
                    title = someString
        }           
    }


    textSize = [title sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:limitSize lineBreakMode:UILineBreakModeWordWrap];
    labelRect = CGRectMake(0, 0, textSize.width, textSize.height);
    NSLog(@"length:%i title:%@",[title length],title);
    NSLog(@"h:%f w:%f",textSize.height,textSize.width);
    if (pickerLabel == nil)
    {
        pickerLabel = [[[UILabel alloc] initWithFrame:labelRect] autorelease];
        [pickerLabel setFont:[UIFont systemFontOfSize:14]];
        [pickerLabel setBackgroundColor:[UIColor clearColor]];
        [pickerLabel setLineBreakMode:UILineBreakModeWordWrap];
        [pickerLabel setTextAlignment:UITextAlignmentCenter];
        [pickerLabel setNumberOfLines:2];
    }

    [pickerLabel setText:title];    

    return pickerLabel;
}

i've manually set the row height at 32.0f. I'm getting very strange results in that some of the Labels in the second component are working perfectly. but others are not wrapping at all, and some are just showing as blank space.

ie: Brussels sprout wraps fine (right component). but Milk and Cream doesn't display (only milk is visible) vegetables doesn't appear at all. Where am i going wrong in my code?


I managed to get it behaving nicely. I changed the last part by removing


textSize = [title sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:limitSize lineBreakMode:UILineBreakModeWordWrap];

and i set the frame manually


labelRect = CGRectMake(0,0,100.0,36.0);

not sure why this worked while the dynamically sized didn't.


Here's a version for swift.

 func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
    var label : UILabel
    if view == nil {
        label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: UIFont.systemFontOfSize(UIFont.systemFontSize()).lineHeight * 2 * UIScreen.mainScreen().scale))
        label.textAlignment = NSTextAlignment.Center
        label.numberOfLines = 2
        label.lineBreakMode = NSLineBreakMode.ByWordWrapping
        label.autoresizingMask = UIViewAutoresizing.FlexibleWidth
    } else {
        label = view as UILabel
    }
    label.text = line1 + "\n" + line2

    return label;
}

func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
    return UIFont.systemFontOfSize(UIFont.systemFontSize()).lineHeight * 2 * UIScreen.mainScreen().scale
}


I corrected your code, in order to let the label width to fit the picker width. I used the koushi approach. It works very well now. See my code here appended.

 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
 {

//assegna i nomi alle caselle del picker e assegna anche la dimensione del font e del rettangolo che contiene le scritte

UILabel *pickerLabel = (UILabel *)view;
CGRect labelRect;

NSString *title=@"";
switch (numberOfComponents){
case 2:
{
    ...gets strings from fetched data (varying length from 4 to 20+)
                title = someString
}
case 3:
{
    ...same as above but for the second set of data.
                title = someString
}           
 }

CGFloat labelWidth=pickerView.frame.size.width-50;
labelRect = CGRectMake( 0,0,labelWidth,45.0);

if (pickerLabel == nil)
{
    pickerLabel = [[UILabel alloc] initWithFrame:labelRect];
    [pickerLabel setFont:[UIFont systemFontOfSize:16]];
    [pickerLabel setBackgroundColor:[UIColor clearColor]];
    [pickerLabel setNumberOfLines:2];
}

[pickerLabel setText:title];    
return pickerLabel;

  }

About your original code: i think that to have a picker with elements of different rect size is not good for appeareance (user experience) matter. I suspect that the different labels rect size is gnerating the problem in your code. If the text that you want to display can be bigger than the defined rect, i think that you should use different app structure approach.

NOTE: in my app i use the picker tag property to identify which picker was selected, because i have more than one picker in my view. For this reason i replaced the "switch" statement in your code with the following code:

  if (pickerView.tag==1)
    title= globalSubcategoryArray[row];
  else
    title= globalAreasName[row];

and obviously i added also:

 -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView.tag==1)
    return globalSubcategoryArray.count;
else    
    return globalAreasName.count;
 }

 -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return  1;
 }



 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (pickerView.tag==1){
    self.subcategoryTextview.text = globalSubcategoryArray[row];
    globalSelectedSubcategoryIndex=row;
    [self.subcategoryTextview resignFirstResponder];

}else{
    self.areaTextview.text= globalAreasName[row];
    globalSelectedAreaIndex=row;
    [self.areaTextview resignFirstResponder];
}

 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜