2013-03-15 50 views
15

我有一个按钮,不同大小的视图。他们都有一个标题和一个图像。我想把图像放在最上面,标题在底部,居中。这工作得很好用下面的代码:设置UIButton titleEdgeInsets和imageEdgeInsets与Autolayout的速度很慢

- (void)centerAlignImageAndTextForButton:(UIButton*)button 
{ 
    CGFloat spacing = 5; 
    CGSize imageSize = button.imageView.frame.size; 
    button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0); 
    CGSize titleSize = button.titleLabel.frame.size; 
    button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width); 
} 

不过,我在进入这个观点之前看到一个小停顿。时间简档在仪器显示,这在viewDidLoad中花99%的时间是通过调用我的方法的按钮引起的:

283.0ms -[XViewController viewDidLoad] 
282.0ms -[XViewController centerAlignImageAndTextForButton:] 
141.0ms  -[UIButton imageView] 
98.0ms  -[UIView(Hierarchy) layoutBelowIfNeeded] 
141.0ms  -[UIButton titleLabel] 
103.0ms  -[UIView(Hierarchy) layoutBelowIfNeeded] 

各种布局相关的东西被称为内[UIView(Hierarchy) layoutBelowIfNeeded],像[UIView(AdditionalLayoutSupport) recursiveLayoutEngineDidChange][NSLayoutConstraint addToEngine]。我知道可以在Interface Builder中设置这些插入符号,但这不仅仅是一项繁琐的工作(需要“猜测”文本的宽度)。该应用程序也将本地化,因此适用于一种语言的插页不会用于其他文本大小不同的另一种插页(我正在使用故事板的基本本地化和.strings文件,而不是为每种语言重复整个故事板)。所以对我来说,似乎以编程方式设置插页是要走的路,但它造成的滞后并不是真的可以接受。

任何想法如何解决?

+0

你为什么不在'layoutSubViews'上设置它们? – orkoden 2016-01-28 15:29:49

回答

6

移动所有从viewDidLoadviewDidLayoutSubviewscenterAlignImageAndTextForButton呼叫从以前的283米的毫秒至18周的毫秒(1周的毫秒为viewDidLoad和17周的毫秒为viewDidLayoutSubviews)减少了装载时间。

不过,我有点不解,为什么会这么贵从viewDidLoad设置这些插图...

+1

也许是因为在viewDidLoad中,你的布局没有被执行,所以还有更多的工作要做?在viewDidLayout中,大部分布局已经完成,所以调整插入是一个调整而不是完整的布局。这是一个猜测。顺便说一句,如果你对按钮的边缘插入感兴趣,我最近在这里写了关于他们(带一个示例项目):http://commandshift.co.uk/blog/2013/03/12/uibutton-edge-插入/ – jrturton 2013-03-15 13:56:28

+1

是的,在寻找解决方案时偶然发现该帖子。你的猜测是有道理的,当在文档中找到'viewDidLayoutSubviews'方法时,我想到了一些类似的想法,这就是为什么我(幸运地)尝试了它。 – 2013-03-15 14:11:49

0

也有类似的问题,从awakeFromNib定制UIButton子缓慢调用titleLabel。由于按钮的大量和/或非平凡的生命周期,移动代码到视图控制器是不合需要的。将代码移动到layoutSubviews没有帮助。最终我将代码移至didMoveToSuperview,并解决了问题。

- (void)didMoveToSuperview 
{ 
    [super didMoveToSuperview]; 
    self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
    self.titleLabel.numberOfLines = 2; 
    self.titleLabel.textAlignment = NSTextAlignmentCenter; 
}