如何将 UILabel 的属性反映到另一个?

Posted

技术标签:

【中文标题】如何将 UILabel 的属性反映到另一个?【英文标题】:How to reflect properties of UILabel to another? 【发布时间】:2016-09-28 09:23:25 【问题描述】:

我正在尝试动态自定义UITableViewController。所以我改变了cell.textLabel 的许多属性。现在我想将这些属性复制到detailTextLabel 和我通过代码创建的一个标签。怎么做?

    cell.textLabel.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
    cell.textLabel.textColor=[UIColor whiteColor];
    cell.textLabel.font=[UIFont fontWithName:@"HelveticaNeue" size:26];
    cell.textLabel.autoresizingMask=UIViewAutoresizingFlexibleRightMargin;

这是我的 cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
        cell.textLabel.text=[_names objectAtIndex:indexPath.row];
        cell.textLabel.tag=indexPath.row;

        cell.detailTextLabel.text=[_phones objectAtIndex:indexPath.row];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png"] ];
        [imageView setFrame:CGRectMake(380,10,30,50)];
        [cell addSubview:imageView];
        //customize the seperator
        UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1000, 1)];/// change size as you need.
        separatorLineView.backgroundColor = [UIColor grayColor];// you can also put image here
        [cell.contentView addSubview:separatorLineView];
        cell.contentView.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
        cell.textLabel.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
        cell.textLabel.textColor=[UIColor whiteColor];
        cell.textLabel.font=[UIFont fontWithName:@"HelveticaNeue" size:26];
        cell.textLabel.autoresizingMask=UIViewAutoresizingFlexibleRightMargin;
        //here i want to copy the properties
        return cell;
    

【问题讨论】:

你能展示一下你的 cellforrowatindextpath 方法吗 创建一个检索这些信息并将其应用到另一个的方法。 @Anbu.Karthik 我已经添加了代码。 @Larme 在编译时,它可能被视为普通方法吗?我不确定 不要像这样在单元格中添加子视图,因为单元格会被重复使用。 【参考方案1】:

对于 Swift3

class MyLabel: UILabel 
    override func draw(_ rect: CGRect) 
        super.draw(rect)
        backgroundColor = UIColor(red: 0, green: 0.188235, blue: 0.313725, alpha: 1)
        textColor = UIColor.white
        font = UIFont(name: "HelveticaNeue", size: 26)
        autoresizingMask = .flexibleRightMargin
    

这样创建UILabel的子类。

#import "MyLabel.h"

@implementation MyLabel

- (void)drawRect:(CGRect)rect 
    [super drawRect:rect];
    self.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
    self.textColor=[UIColor whiteColor];
    self.font=[UIFont fontWithName:@"HelveticaNeue" size:26];
    self.autoresizingMask=UIViewAutoresizingFlexibleRightMargin;


@end

现在创建这个 MyLabel 的一个对象,您的属性将自动设置,并且只需通过情节提要将此类分配给您的标签到您的单元格中的标签。

子类化是实现可重用代码的最佳方式。

否则,您甚至可以在某个接受UILabel 并设置属性的类中创建类的扩展,甚至是类方法,但这并不是最佳实践。扩展的另一个问题是您只能使用self 而不能使用super。当您必须扩展属性时,这可能会在将来产生问题。

我希望我说得清楚且有帮助。

【讨论】:

【参考方案2】:

您可以使用此方法将UITabelViewCell的所有标签设为同一属性

这里只是循环遍历子视图,检查子视图是否为UILabel,如果是UILabel,则设置你想要的属性。

我的代码:

- (void)formatTheLabelForCell:(UITableViewCell *)cell

    for (UIView *view in cell.contentView.subviews) 
        if ([view isKindOfClass:[UILabel class]]) 
            UILabel *lbl = (UILabel *)view;

            lbl.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
            lbl.textColor=[UIColor whiteColor];
            lbl.font=[UIFont fontWithName:@"HelveticaNeue" size:26];
            lbl.autoresizingMask=UIViewAutoresizingFlexibleRightMargin;
        
    

【讨论】:

它工作正常。我想知道是否有任何代码可以在 XCode 编辑器中动态复制和粘贴工具。 我已经从“cellForRowAtIndexPath”中调用了您的“formatTheLabelForCell”,但我在 100 左右的“ViewController”中有很多原始数据,因此需要更长的时间。每次在创建单元格时循环浏览视图 不建议同时加载这么多单元格。就算你不使用load more,你是不是一次在屏幕上显示100个cell?? 是的,我有。这是客户的需求。【参考方案3】:

与其在cellForRowAtIndexPath 中配置单元格,不如使用自定义单元格。在您的故事板/笔尖本身中添加imageViewseparatorLineView。这样,所有单元格都是使用这些默认属性生成的。此外,如果您需要通过代码进行配置,您可以在 CustomCell.m 文件中编写代码,如下所示:

 class CustomCell: UITableViewCell 
    override func awakeFromNib() 
    super.awakeFromNib()
    self.textLabel.backgroundColor = UIColor.redColor
    //do other configurations
    

编辑:从网络下载图像可能是加载单元格需要很长时间的原因。尝试异步下载图像。你也可以使用这个库:SDWebImage

注意:我知道你想在 Objective C 中使用它,上面的 Swift 代码只是为了说明。

【讨论】:

【参考方案4】:

至于swift,你可以这样做,它会将你应用于textLabel的所有属性复制到detailTextLabel。

 cell.detailTextLabel.attributedText = cell.textLabel.attributedText

【讨论】:

【参考方案5】:

首先,我认为 ios SDK 中没有复制任何 UIKit 组件的特定属性的功能。因此,您将不得不为此编写一个自定义函数。此外,正如 cmets 中的其他人指出的那样,您的“cellForRowAtIndexPath”存在一些问题。

对此有不同的解决方案。

解决方案 1: 在您的视图控制器中编写一个函数,该函数将两个标签作为参数并复制您想要的值。

-(void)copyPropertiesFrom:(UILabel*)label1 toLabel:(UILabel*)label2
    label2.backgroundColor  = label1.backgroundColor;
    label2.textColor        = label1.textColor;
    label2.font             = label1.font;
    label2.autoresizingMask = label1.autoresizingMask;

在要复制的 cellForRowAtIndexPath 中执行此操作

[self copyPropertiesFrom:cell.titleLabel toLabel:cell.detailTextLabel];

解决方案 2(推荐):这在我的小经验中是最好的,因为您可以在其他视图控制器中重用它。可能有比这更好的方法。

创建一个 UILabel 类别。检查此链接How do I create a category in Xcode 6 or higher? 以及此https://code.tutsplus.com/tutorials/objective-c-categories--mobile-10648

类别中的函数将如下所示。

-(void)formatLabelToMyStyle
    self.backgroundColor    = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
    self.textColor          = [UIColor whiteColor];
    self.font               = [UIFont fontWithName:@"HelveticaNeue" size:26];
    self.autoresizingMask   = UIViewAutoresizingFlexibleRightMargin;

您将包含类别的头文件并像这样在 cellForRowAtIndexPath 中调用此函数

[cell.titleLabel formatLabelToMyStyle];
[cell.detailTextLabel formatLabelToMyStyle];
[cell.customTextLabel formatLabelToMyStyle];

至于您的 cellForRowAtIndexPath,larme 在 cmets 中提到“不要在单元格中添加子视图,因为单元格被重复使用”这将继续向您的单元格添加视图,从而导致内存问题,特别是当您有大量单元格时在你的情况下是真的。

【讨论】:

【参考方案6】:

您可以将Category 用于UILabel 或使用UILabel 的子类,它们应该共享相同的样式。

UILabelCategory 可能如下所示:

// UILabel+CustomStyle.h
#import <UIKit/UIKit.h>

@interface UILabel (CustomStyle)
-(void) applyCustomStyle;
@end

.m 文件:

// UILabel+CustomStyle.m
#import "UILabel+CustomStyle.h"

@implementation UILabel (CustomStyle)

-(void) applyCustomStyle 
    self.backgroundColor = [UIColor colorWithRed: 0 green: 0.188235 blue: 0.313725 alpha: 1];
    self.textColor = [UIColor whiteColor];
    self.font = [UIFont fontWithName: @"HelveticaNeue" size: 26];
    self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;


@end

然后您可以通过简单地调用来应用相同的样式:

#import "UILabel+CustomStyle.h"
[label applyCustomStyle];

【讨论】:

【参考方案7】:

如果您想在项目中的许多地方使用相同的标签配置。就像@NikhilManapure 所说的那样子类化。

如果您想对 TableViewCell textLabeldetailTextLabel 应用相同的属性。您应该继承 TableViewCell 并在 drawrect 方法中覆盖 Label 属性。

目标-C

        #import <UIKit/UIKit.h>

        @interface PropertiesCell : UITableViewCell

        @end

        #import "PropertiesCell.h"

        @implementation PropertiesCell

        - (void)awakeFromNib 
            [super awakeFromNib];
            // Initialization code
        

        - (void)setSelected:(BOOL)selected animated:(BOOL)animated 
            [super setSelected:selected animated:animated];

            // Configure the view for the selected state
        

        - (void)drawRect:(CGRect)rect 
            [super drawRect:rect];
            [self cellLabelConfigure:self.textLabel];
            [self cellLabelConfigure:self.detailTextLabel];
        

        - (void)cellLabelConfigure:(UILabel*) contentLabel 
            contentLabel.backgroundColor = [UIColor colorWithRed:0 green:0.188235 blue:0.313725 alpha:1];
            contentLabel.textColor=[UIColor whiteColor];
            contentLabel.font=[UIFont fontWithName:@"HelveticaNeue" size:26];
            contentLabel.autoresizingMask=UIViewAutoresizingFlexibleRightMargin;
        

        @end

斯威夫特

 class PropertiesCell: UITableViewCell 
    override func draw(_ rect: CGRect) 
        super.draw(rect)
        cellLabelsConfigure(contentLabel: self.textLabel)
        cellLabelsConfigure(contentLabel: self.detailTextLabel)
    

    func cellLabelsConfigure(contentLabel: UILabel?) 
        contentLabel?.backgroundColor = UIColor(red: 0.0, green: 0.188, blue: 0.313, alpha: 1.0)
        contentLabel?.textColor = UIColor.white
        contentLabel?.font = UIFont(name: "HelveticaNeue", size: 26.0)
        contentLabel?.autoresizingMask = UIViewAutoresizing.flexibleRightMargin
    

在情节提要中将单元格类名称更改为 PropertiesCell

【讨论】:

【参考方案8】:

创建一个扩展类并使用此copy 方法将您想要的所有属性传递给新标签。

@implementation UILabel (Copy)

- (UILabel *)copyProperties 
    UILabel *label = [UILabel new];
    [self copyPropertiesWithLabel:label];
    return label;


- (void)copyPropertiesWithLabel:(UILabel *)label 
    label.backgroundColor = self.backgroundColor;
    label.textColor = self.textColor;
    label.font = self.font;
    label.autoresizingMask = self.autoresizingMask;
    // Add more properties


@end

用法:

// cell.textLabel has now all the properties
[theLabelToBeCopied copyPropertiesWithLabel:cell.textLabel];

【讨论】:

【参考方案9】:

Swift3 版本:

extension UILabel 

    func copyProperties() -> UILabel 
        var label = UILabel()
        self.copyProperties(with: label)
        return label
    

    func copyProperties(with label: UILabel) 
        label.backgroundColor = self.backgroundColor
        label.textColor = self.textColor
        label.font = self.font
        label.autoresizingMask = self.autoresizingMask
        // Add more properties
    

用法:

theLabelToBeCopied.copyProperties(with: cell.textLabel)

【讨论】:

【参考方案10】:

您可以为 swift 执行此操作。它将复制所有属性(textLabel 到 detailTextLabel)。我认为 @Nikhil Manapure 给出了确切的答案。

cell.detailTextLabel.attributedText = cell.textLabel.attributedText

【讨论】:

以上是关于如何将 UILabel 的属性反映到另一个?的主要内容,如果未能解决你的问题,请参考以下文章

IOS-OC-基本控件之UILabel

UILabel 重绘视图。如何避免这种行为?

将 UILabel 的层添加到另一个层(单独的 UIView)

如何将 CGFloat 设置为 UILabel 的文本属性

如何为 UILabel 的 textColor 属性设置动画?

将数据从一个 ViewController 中的 UITextField 传递到另一个 View Controller 中的 UILabel