frame 控制 UIView 大小和位置。每個 UIView 內部關聯了一個 CALayer,跟顯示相關的屬性儲存在 CALayer 中。UIView 內部並沒有儲存 frame 這個欄位,而是由 CALayer 的 position、bounds、transform、anchorPoint 等欄位動態計算出來的。UIView 修改了 frame 欄位,就間接修改了 CALayer 的顯示相關屬性;同樣修改了 CALayer 的屬性,也間接修改了 UIView 的 frame。
sizeToFit 呼叫了 sizeThatFits 這個函式。而 sizeThatFits 讓每個 UIView 的子類來實現,根據需要顯示的內容計算出最適當的大小。sizeToFit 使用 sizeThatFits 的計算結果修改 frame 的大小。
button 的寬高也是由 frame 決定的。修改 frame 可以修改 button 的大小。
4. 點選區域是由 UIView 的 hitTest 函式控制的,通常實現是根據 UIView 的顯示區域來判斷是否選中某個 view, 之後 touch 的事件就讓選中的 view 來處理。但是 hitTest 可以改寫,改寫之後,就算顯示區域很小,點選區域也可以很大。顯示區域跟點選區域可以分離。
題主的疑問是,為什麼我在點選事件中,明明透過 sizeToFit 修改了 button 的大小,但 button 的顯示區域沒有改變呢?題主忽略了一點,除了你自己呼叫程式碼來修改 frame, UIKit 實現也是可以修改 frame 的。當 button 新增到 navigationItem 的 titleView 中,你呼叫了程式碼修改了 frame 值,frame 值這時候確實改變了。但之後內部實現再次修改了 button 的 frame,將其還原了。因此看到 button 的大小沒有變化。
可以做個試驗,如下的程式碼,buttonPressed 中將新舊的 frame 打印出來。
可以看到每次修改 frame 之後,會再次還原成原來的大小。那什麼時候被還原的呢?可以繼承 UIButton, 改寫 frame 屬性,在其中設定斷點。在 buttonPressed 被呼叫之後,setFrame 函式會再次被系統觸發。
frame 控制 UIView 大小和位置。每個 UIView 內部關聯了一個 CALayer,跟顯示相關的屬性儲存在 CALayer 中。UIView 內部並沒有儲存 frame 這個欄位,而是由 CALayer 的 position、bounds、transform、anchorPoint 等欄位動態計算出來的。UIView 修改了 frame 欄位,就間接修改了 CALayer 的顯示相關屬性;同樣修改了 CALayer 的屬性,也間接修改了 UIView 的 frame。
sizeToFit 呼叫了 sizeThatFits 這個函式。而 sizeThatFits 讓每個 UIView 的子類來實現,根據需要顯示的內容計算出最適當的大小。sizeToFit 使用 sizeThatFits 的計算結果修改 frame 的大小。
button 的寬高也是由 frame 決定的。修改 frame 可以修改 button 的大小。
4. 點選區域是由 UIView 的 hitTest 函式控制的,通常實現是根據 UIView 的顯示區域來判斷是否選中某個 view, 之後 touch 的事件就讓選中的 view 來處理。但是 hitTest 可以改寫,改寫之後,就算顯示區域很小,點選區域也可以很大。顯示區域跟點選區域可以分離。
題主的疑問是,為什麼我在點選事件中,明明透過 sizeToFit 修改了 button 的大小,但 button 的顯示區域沒有改變呢?題主忽略了一點,除了你自己呼叫程式碼來修改 frame, UIKit 實現也是可以修改 frame 的。當 button 新增到 navigationItem 的 titleView 中,你呼叫了程式碼修改了 frame 值,frame 值這時候確實改變了。但之後內部實現再次修改了 button 的 frame,將其還原了。因此看到 button 的大小沒有變化。
可以做個試驗,如下的程式碼,buttonPressed 中將新舊的 frame 打印出來。
可以看到每次修改 frame 之後,會再次還原成原來的大小。那什麼時候被還原的呢?可以繼承 UIButton, 改寫 frame 屬性,在其中設定斷點。在 buttonPressed 被呼叫之後,setFrame 函式會再次被系統觸發。