UIButton 如何变相获取 titleLabel.frame

作者: AnLuoRidge | 来源:发表于2016-10-02 11:28 被阅读1447次

    Keywords: UIButton, titleLabel, imageView, frame, bounds, size, width

    如果你读过 [iOS]调整UIButton的title和image详解 - 简书stackOverFlow 上的这篇 ,会发现获取一个 size 属性是个多大的坑……因为自 iOS8 起,一个 UIButton 内部的 titleLabel / imageView 的 frame / bounds 只有等这个按钮完成了自己的初始化后才会生成(据我推测~)。

    因此,iOSers 发明了许多诡异的获取 size 的方法。比如提前[self setNeedsLayout]; [self layoutIfNeeded];,或者提前调用一下 titleLabel / imageView 的属性,或者将获取 size 放入 dispatch_async(dispatch_get_main_queue()...中。这些我统统试过,然而都不好用。

    那怎么获取呢?答案是:[titleLable.text sizeWithAttributes: userAttributes].width

    PS: 已经加载按钮后,要根据文字变化,动态改变按钮的 frame 要重新加载按钮……很麻烦。


    篇二:控件如何绑定类方法?

    keywords: class method, UIButton, 按钮, addTarget, action

    [xxxTextField addTarget:[SomeClass class]
                          action:@selector(method)
                forControlEvents:UIControlEventXxx];
    

    篇三:如何在 UITextField 的委托方法中重设一个复杂的占位符(placeholder)

    按:需求合理而实现诡异的情况总是层出不穷……

    Q1: 什么样的合理需求?
    A1: 用户点击输入框,占位符消失。若 TA 离开时没有输入任何文本,则占位符得重新变回来。

    Q2: 什么叫复杂的占位符?
    A2: 包括但不限于:与「输入时」(Editing Time?) 不同的对齐方式,由 NSAttributedString 创建,同时根据不同机型还做了字号缩放之类的适配……

    栗子(兼解决方案):

    - (void)setMonthTextFieldPlaceholder:(UITextField *)tf {
      
      if ((is4S || is5S) && (isEN || isTh)) {// Thailand
        tf.textAlignment = NSTextAlignmentCenter;
        tf.attributedPlaceholder =
        [[NSAttributedString alloc] initWithString:NSLocalizedString(@"card_month", nil)
                                        attributes:@{
                                                     NSFontAttributeName : [UIFont systemFontOfSize:contentFontSize - 1]
                                                     }
         ];
      } else {
          tf.placeholder = NSLocalizedString(@"card_month", nil);
          tf.textAlignment = NSTextAlignmentRight;
        }
    

    解释:在 View 中创建 textField 时,就把设置占位符的部分单独用一个函数来写。(由于指针的关系,对形参的操作可直接影响实参~)再把这个设置方法暴露在头文件里。

    使用:比如在委托方法- (void)textFieldDidEndEditing:(UITextField *)textField 你就可以通过:

    if (!textField.text.length) {
      [someView setMonthTextFieldPlaceholder:textField];
    }
    

    来轻松重设一个「复杂的」占位符了~


    PS: 实际的需求其实更麻烦,某些语言占位符要居右,而开始输入时要居中。然而只要占位符在,那么光标要么居左要么居右,设置居中是不行的,所以要提前把 palceholder = nil。
    如果之后用户没输入,再调用 setPlaceholder 方法……

    PS2: shouldChangeCharactersInRange:(NSRange)range 是有坑的,原理我也不清楚。具体情况是:从空 textField 输入时的 range.location 与 编辑一个已有内容的 textField(比如从父界面传回了一些数据)时的 range.location 差了一位(内容统一长度的话)。有的 location 起始是这样的:nil, 2, 3,有的是 nil, 1, 2...

    相关文章

      网友评论

      • 洁简:userAttributes 是?
      • Lol刀妹:可以,小伙子
        AnLuoRidge:@无夜之星辰 :grin:
      • 610bbc7fc2d5:看完我只想说,果然隔行如隔山😲
        AnLuoRidge:@初眉 大地是我家~
        610bbc7fc2d5:@AnLuoRidge 高端技术党你好!请给我大腿带我飞(๑• . •๑)
        AnLuoRidge:@初眉 虽然它有正在变成技术博客的倾向……但有机会我还是写点正常的文字吧(*^ω^*)

      本文标题:UIButton 如何变相获取 titleLabel.frame

      本文链接:https://www.haomeiwen.com/subject/koldyttx.html