2013-03-15 51 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; 
}