UIButton titleLabel帧大小返回CGSize,零宽度&高度

时间:2014-09-10 06:22:12

标签: ios ios8

对于iOS7,我使用UIButton titleLabel.frame.size.width属性来确定不同本地化下我的按钮标题的宽度,以便我可以使用contentInsetUIButton上正确定位标题}。

我的UIButton设置了图片和标题,我总是希望这两者的组合在UIButton中水平居中,例如:

[space-x (image) space-y (titleLabel) space-x]

在iOS 7和Xcode 5.1下,以下代码完美运行(甚至在内置于XCode 5.1时在iOS 8 GM上运行):

CGSize buttonSize = button.frame.size;
CGSize titleSize = button.titleLabel.frame.size;
float contentInset =((buttonSize.width - (titleSize.width + 18 + 3)) / 2 );
float contentInsetRounded = roundf(contentInset);
[button setContentEdgeInsets:(UIEdgeInsetsMake(0, contentInsetRounded, 0, 0))];

(18是图像的宽度,3是图像与我上例中的titleLabel或空格-Y之间的间距数)

在iOS 8和Xcode 6 GM下,button.titleLabel.frame.size返回CGSize,零宽度&高度,所以我的contentInset最终使UIImage中的UIButton居中,导致titleLabel截断。

有什么想法吗?我尝试在此代码之前立即设置titleLabel文本,以防它认为它是空的但是也没有帮助。

提前致谢!

6 个答案:

答案 0 :(得分:15)

设置标题文本,然后为标题标签创建sizeToFit,并尝试获取titleLabel.frame.size.width

[myButton setTitle:@"My Title" forState:UIControlStateNormal];
[myButton.titleLabel sizeToFit];

答案 1 :(得分:13)

解决了它。应用程序在iOS8上运行,由Xcode 6构建,而不是在UIButton setTitlesetTitleEdgeInsets之后立即更新框架。它将等待下一次UI更新。所以,如果你获得了titleLabel的框架,你将获得CGRectZero。

<强>解决方案

  1. 在设置UI属性后调用以下方法,立即更新布局:

    [self setNeedsLayout];
    [self layoutIfNeeded];

  2. 或者:

    1. 延迟一秒,您可以titleFrame使用self.titleLabel.frame
    2. 或者:

      1. 主队列中的dispatch_async,用于将代码移动到下一个队列

答案 2 :(得分:1)

如果您在获取框架后在按钮旁边设置图像,则可以使用

[theButton setTitle: @"theTitle" forState:UIControlStateNormal];
[theButton setImage: theImage forState:UIControlStateNormal];
[theButton setNeedsLayout];
[theButton layoutIfNeeded];
[theButton setImageEdgeInsets: UIEdgeInsetsMake(6, transactionsButton.titleLabel.frame.size.width + 40.0, 0, 0)];

在Swift 3中,这样做。

self.view.layoutIfNeeded()

答案 3 :(得分:0)

也许这对你不起作用,但是在XCode 6 GM / iOS8中运行我的代码并且无法使其工作时我遇到了同样的问题。它随机工作,我最终使用了一种不同的方法而不是NSString我使用了NSAttributedString作为标题。

NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:@"Button text"];
NSTextAttachment* textAttachment = [NSTextAttachment new];
textAttachment.image = [UIImage imageNamed:@"Arrows"];
NSAttributedString *finalString = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedText appendAttributedString:finalString];

唯一需要注意的是它是iOS7及以上,但似乎完美无瑕。

答案 4 :(得分:0)

事实证明,我已经将自己设计成了这个问题。我拿出了所有内容的嵌入代码,因此不需要找到frame.size。我现在只是按钮标题的中心,一切都很好!

似乎仍然存在获取frame.size的问题但是根据我的需要,我可以解决它。

答案 5 :(得分:0)

所以我们可以试试这段代码:

func withTitleAndImageAlign(title:String,image:UIImage,RL_Space:CGFloat) {
        setNeedsLayout()
        layoutIfNeeded()
        let buttonWidth = frame.size.width
        let textWidth = titleLabel?.frame.size.width
        let imageWidth = imageView?.frame.size.width
        let lim = buttonWidth  - (textWidth! + imageWidth! + (2 * RL_Space) )
        imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: lim)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: lim, bottom: 0, right: 0)
    }