【问题标题】:How to set a subview's frame to be its parent's frame in a custom view如何在自定义视图中将子视图的框架设置为其父框架
【发布时间】:2014-02-18 05:23:23
【问题描述】:

我想将自定义视图的框架设置为我的子视图的框架,它是一个 UILabel。但 当我使用 self.frame 时,UILabel 显示空文本。我需要硬编码CGRectMake 中的参数才能看到我的UILabel。如何将 UILabel 的框架设置为我的自定义视图的框架?

- (id)initWithFrame:(CGRect)frame withText:(NSString *)text
{
    self = [super initWithFrame:frame];

    if (self) {
        self.backgroundColor = [UIColor grayColor];
        self.layer.cornerRadius = 3;
        self.layer.borderWidth = 1;
        self.layer.borderColor = [UIColor blackColor].CGColor;
        _text = text;
    }

    return self;
}

- (void)layoutSubviews
{
    // This works
    // UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 40)];
    // This doesn't work
    UILabel *label = [[UILabel alloc] initWithFrame:self.frame];
    label.text = @"";
    if (![self.text isEqualToString:@"?"]) {
        label.text = self.text;
        label.textAlignment = NSTextAlignmentCenter;
    }

    [self addSubview:label];
}

【问题讨论】:

    标签: ios objective-c cocoa-touch uiview subview


    【解决方案1】:

    layoutSubviews 会被多次调用,所以你不应该这样addSubview。更好的风格是设置 UILabel 的属性,比如你的 text 属性:

    @property (nonatomic, strong) UILabel * label;
    

    然后更改您的layoutSubviews 代码:

    - (void)layoutSubviews
    {
        if(!self.label){
             self.label = [[UILabel alloc] initWithFrame:self.frame]; //Use ARC
             self.label.textAlignment = NSTextAlignmentCenter;
             [self addSubview:self.label];
        }
    
        self.label.frame = self.bounds;
        if (![self.text isEqualToString:@"?"]) {
            self.label.text = self.text;
        }
    }
    

    【讨论】:

    • 这是个坏主意。您不想在 layoutSubviews 方法中创建视图。它可以被多次调用,通常在某些情况下,因此每次都检查是否已经创建了标签会影响性能。如果您打算将初始帧设置为 self.frame 而不是 self.bounds ,那么为什么要将其更改为下面几行的边界?此外,在此函数中设置 label.text 属性是一个坏主意。您无法控制何时调用此方法。
    • 当然!将初始化视图放入 initWithFrame: 即可。我的代码是懒加载的风格,把init代码放在view开始使用的地方会更好。因为显示的代码是有限的,所以我只是把它放在 layoutSubviews 中。 @戴夫伍德
    【解决方案2】:

    试试下面的代码。

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 70, 40)]; // set frame as you want
    label.backgroundColor = [UIColor yellowColor]; // set color as you want
    label.text = @"Hellow";
    [yourParentView addSubview:label];
    

    【讨论】:

      【解决方案3】:

      使用此代码

      - (id)initWithFrame:(CGRect)frame withText:(NSString *)text
      {
          self = [super initWithFrame:frame];
      
          if (self) {
              self.backgroundColor = [UIColor grayColor];
              self.layer.cornerRadius = 3;
              self.layer.borderWidth = 1;
              self.layer.borderColor = [UIColor blackColor].CGColor;
              _text = text;
      
           [self layoutSubviews:frame];
          }
      
          return self;
      }
      
      - (void)layoutSubviews:(CGRect)myFrame
      {
          // This works
          // UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 40)];
          // This doesn't work
          UILabel *label = [[UILabel alloc] initWithFrame:myFrame];
          label.text = @"";
          if (![self.text isEqualToString:@"?"]) {
              label.text = self.text;
              label.textAlignment = NSTextAlignmentCenter;
          }
      
          [self addSubview:label];
      }
      

      【讨论】:

        【解决方案4】:

        您不想在layoutSubviews 方法中创建视图。该方法可以被多次调用,并且您将多次创建每个视图(让它们相互重叠)。

        改为在initWithFrame 方法中创建您需要的视图。

        对于您的实际问题的答案,您可能需要将新标签的框架设置为自定义视图的边界。边界的原点为 0,0,因此无论自定义视图放置在其父视图中的哪个位置,它都将起作用。如果您使用框架,标签将偏移自定义视图的偏移量。

        您可能可以完全删除您的 layoutSubviews 方法,因为这也不是设置标签文本的地方。然后添加:

        - (instancetype)initWithFrame:(CGRect)frame withText:(NSString *)text
        {
            self = [super initWithFrame:frame];
            if (!self) return nil;
        
            self.backgroundColor = [UIColor grayColor];
            self.layer.cornerRadius = 3;
            self.layer.borderWidth = 1;
            self.layer.borderColor = [UIColor blackColor].CGColor;
            _text = text;
        
            UILabel *label = [[UILabel alloc] initWithFrame:self.bounds];
            label.text = @"";
            if (![self.text isEqualToString:@"?"]) {
                label.text = self.text;
                label.textAlignment = NSTextAlignmentCenter;
            }
        
            [self addSubview:label];
        
            return self;
        }
        

        如果您希望在自定义视图调整大小时调整标签大小,您可以通过设置 label.frame = self.bounds; 在 layoutSubviews 中执行此操作,但最好使用自动调整大小掩码或自动布局。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多