带有多行 UILabel 的 UIPickerView

Posted

技术标签:

【中文标题】带有多行 UILabel 的 UIPickerView【英文标题】:UIPickerView with Multiline UILabel 【发布时间】:2009-12-08 06:30:55 【问题描述】:

我目前正在开发一个程序,该程序可以从我的核心数据设置中动态填充选择器视图。我的一切都在数据方面工作,但我现在遇到的问题是我的标签上的格式。

选择器在操作表中显示了它自己的工具栏,工具栏右侧有一个按钮。它的初始状态是可见 2 个刻度盘。按下按钮时,它变为 3 个刻度盘。

- (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;

我已手动将行高设置为 32.0f。我得到了非常奇怪的结果,因为第二个组件中的一些标签工作得很好。但其他人根本没有换行,有些人只是显示为空白。

ie:球芽甘蓝包裹得很好(右组件)。但牛奶和奶油不显示(只有牛奶可见)蔬菜根本不出现。我的代码哪里出错了?

【问题讨论】:

谢谢,这对我很有帮助。 【参考方案1】:

我设法让它表现得很好。我通过删除更改了最后一部分


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

我手动设置框架


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

不知道为什么这在动态调整大小时不起作用。

【讨论】:

【参考方案2】:

这是 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

【讨论】:

【参考方案3】:

我更正了您的代码,以便让标签宽度适合选择器宽度。 我使用了koushi方法。现在效果很好。 请在此处查看我的代码。

 - (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;

  

关于您的原始代码:我认为拥有一个具有不同矩形大小的元素的选择器不利于外观(用户体验)问题。我怀疑不同的标签矩形大小会在您的代码中产生问题。如果您要显示的文本可以大于定义的矩形,我认为您应该使用不同的应用程序结构方法。

注意:在我的应用程序中,我使用选择器标签属性来识别选择了哪个选择器,因为我的视图中有多个选择器。出于这个原因,我用以下代码替换了您代码中的“switch”语句:

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

显然我还添加了:

 -(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];


 

【讨论】:

以上是关于带有多行 UILabel 的 UIPickerView的主要内容,如果未能解决你的问题,请参考以下文章

iOS:多行 uilabel 仅显示带有自动布局的一行

带有多行 UILabel 的 UIPickerView

UICollectionViewCell 的高度,带有 2 个多行 UILabel / 自调整大小的集合视图单元格

多行 UILabel 高度,横向自动布局更高

UITableViewCell 中的 UIStackView 与多行 UILabel

基于多行 UILabel 自动调整 UIView 的大小