自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Auto Layout處理比例間距問(wèn)題

移動(dòng)開(kāi)發(fā) iOS
在這篇文章中我想著眼于一個(gè)經(jīng)常出現(xiàn)的情形: 你需要沿一個(gè)軸向按固定比例放置視圖??赡懿⒉皇鞘置黠@, 但是這個(gè)需求可以通過(guò) 一個(gè)multiplier中心對(duì)齊來(lái)輕松實(shí)現(xiàn),它是一種在有無(wú)Stack Views情況下都可以使用的技術(shù)。

Auto Layout 是一個(gè)掌握起來(lái)很具有挑戰(zhàn)性的東西。iOS 9引入的 Stack Views 和 layout 錨點(diǎn)有一些幫助,但是明白如何創(chuàng)建特定的 layout仍有一定難度。

在這篇文章中我想著眼于一個(gè)經(jīng)常出現(xiàn)的情形: 你需要沿一個(gè)軸向按固定比例放置視圖。可能并不是十分明顯, 但是這個(gè)需求可以通過(guò) 一個(gè)multiplier中心對(duì)齊來(lái)輕松實(shí)現(xiàn),它是一種在有無(wú)Stack Views情況下都可以使用的技術(shù)。

問(wèn)題

設(shè)想我們要構(gòu)建這樣一個(gè)布局,上面有兩排圖片視圖,都是基于父視圖寬度和高度的某一百分比放置。之所以使用圖片視圖, 是因?yàn)槿绻馔獾匕阉鼈兝旎驂嚎s了, 可以十分明顯得看出來(lái)。

當(dāng)視圖適應(yīng)不同的屏幕大小時(shí), layout 會(huì)保持相同的比例。下面是同一個(gè)視圖在橫屏模式下的情形:

一旦你看出來(lái)我們是基于視圖中心進(jìn)行對(duì)齊的,你就會(huì)發(fā)現(xiàn)我們可以只使用中心對(duì)齊約束來(lái)創(chuàng)建整個(gè)布局。對(duì)每個(gè)imageView,我們需要一對(duì)約束來(lái)確定其在X軸和Y軸的位置,一般的格式是這樣的:

  1. imageView.CenterX = view.CenterX * modifier  
  2. imageView.CenterY = view.CenterY * modifier 

modifier參數(shù)將imageView放置在父視圖尺寸的某個(gè)百分比的位置上,如下所示:

寓教于樂(lè)。這里有三種方式來(lái)創(chuàng)建該布局,***是使用 IB, 第二是用代碼添加約束,第三是使用 stack view.

使用Interface Builder創(chuàng)建約束

對(duì)每個(gè) image view 我們需要添加兩個(gè)約束。使用文檔大綱工具欄或者直接在視圖畫(huà)布中按住 control 鍵從 image view 中拖拽到父視圖上。每一個(gè)都添加一個(gè)“Center Horizontally in Container”和“Certer Vertically in Container”約束。

 

現(xiàn)在, 編輯每個(gè)約束來(lái)設(shè)置我們需要的百分比例。下面是左上角的紅心圖片視圖的水平和垂直約束設(shè)置:

注意這也是給我們的約束添加identifiers 的好時(shí)機(jī)。完成后,你應(yīng)該添加了10個(gè)約束,如下所示:

以代碼形式創(chuàng)建約束

在看添加約束的代碼之前,我要提下一個(gè)常見(jiàn)的錯(cuò)誤,當(dāng)使用代碼添加視圖時(shí), 你需要關(guān)閉視圖的 autoresizing mask 向 constraints 的轉(zhuǎn)變。如果不這樣做,系統(tǒng)會(huì)自動(dòng)創(chuàng)建約束,這會(huì)和我們創(chuàng)建的約束發(fā)生沖突。

  1. //...code to create image view...  
  2. imageView.translatesAutoresizingMaskIntoConstraints = false 
  3. view.addSubview(imageView) 

有幾種創(chuàng)建這些約束的方法,我將會(huì)在視圖控制器的 viewDidLoad 方法中創(chuàng)建. 一個(gè)簡(jiǎn)單的輔助函數(shù)會(huì)使創(chuàng)建每個(gè) NSLayoutConstraint 的過(guò)程不那么麻煩:

  1. func addConstraintFromView(subview: UIView?,  
  2.                          attribute: NSLayoutAttribute,  
  3.                         multiplier: CGFloat,  
  4.                         identifier: String) {  
  5.   if let subview = subview {  
  6.     let constraint = NSLayoutConstraint(item: subview,  
  7.             attribute: attribute,  
  8.             relatedBy: .Equal,  
  9.             toItem: view,  
  10.             attribute: attribute,  
  11.             multiplier: multiplier,  
  12.             constant: 0)  
  13.     constraint.identifier = identifier  
  14.     view.addConstraint(constraint)  
  15.   }  
  16.      

這樣就可以創(chuàng)建并添加一個(gè)相對(duì)于父視圖的約束 (使用視圖控制器的 view 屬性)。NSLayoutAttribute 參數(shù)在水平約束中為 .CenterX,在豎直約束中為 .CenterY。例如,下面是上面一行的紅心圖片視圖的約束:

  1. // vertical constraint  
  2. addConstraintFromView(heartTop,  
  3.               attribute: .CenterY,  
  4.              multiplier: 0.667,  
  5.              identifier: "heartTop center Y")  
  6.                 
  7. // horizontal constraint  
  8. addConstraintFromView(heartTop,  
  9.               attribute: .CenterX,  
  10.              multiplier: 0.5,  
  11.              identifier: "heartTop center X"

剩下的和這個(gè)類似,全部設(shè)置見(jiàn)示例代碼。

使用Stack View呢?

無(wú)論何時(shí)只要你遇到水平或垂直布局的問(wèn)題,你就要想到 stack view。向 stack view 中添加 image views 是很簡(jiǎn)單的,但是如何配置呢? 我們不想讓stack view中堆滿views, 所以 Axis 選擇水平軸向, 使用“Equal Spacing”分布方式:

現(xiàn)在我們需要約束 stack view 的大小和位置:

  • 使用和設(shè)置圖片視圖豎直位置相同的方式設(shè)置每個(gè) stack view 的豎直位置。使用modifier中心約束 (例如頂部 stack view 使用 stackView.centerY = 0.667 * superview.centerY 約束)。
  • 向每個(gè) stack view 添加一個(gè)水平居中的約束。
  • ***的約束需要一點(diǎn)小小的技巧,我們需要確定 stack view 的寬度,使用 stack view 的 leading 和 trailing 邊緣是最簡(jiǎn)單的方式:

左上的 image view 的中心應(yīng)該是父視圖中心的 0.5 倍. 那么我們需要 stack view 的左邊向左移動(dòng)image view 寬度的一半. image view 大小時(shí) 100x100, 所以我們需要在約束中減去 50:

注意在 IB 中添加這個(gè)約束時(shí)你需要改變第二項(xiàng)為 superview center,equal spacing 分布方式將會(huì)為我們修正 trailing 位置. 用類似的方法處理下方的 stack view,于是我們最終結(jié)果如下:

這是我發(fā)現(xiàn)的一種用代碼添加約束要比在IB中編輯簡(jiǎn)單得多的一種情形,尤其是當(dāng)我們可以在運(yùn)行時(shí)計(jì)算 image view 的大小時(shí)。

2016-01-31 更新: 還有一個(gè)更簡(jiǎn)單的方法,為最左邊圖片的中心添加一個(gè)約束,stack view 會(huì)改變大小來(lái)適應(yīng),而不需要計(jì)算圖片的大小。詳見(jiàn)代碼。

補(bǔ)充閱讀

你可以在 GitHub CodeExamples 上找到這篇帖子的代碼,它包含IB、代碼和 stack view 三個(gè)版本,你可以比較下這幾個(gè)方法。

責(zé)任編輯:陳琳 來(lái)源: CocoaChina
相關(guān)推薦

2009-09-17 13:08:07

NIS配置auto_dire

2021-10-21 09:00:00

機(jī)器學(xué)習(xí)技術(shù)工具

2010-09-02 10:16:43

fixedCSS

2023-11-28 15:18:24

Python

2009-08-27 09:57:05

Linux谷歌搜索Bing

2024-04-07 09:00:00

MySQL

2024-02-19 09:27:31

谷歌AI

2023-09-22 22:27:54

autoC++11

2011-08-22 13:28:56

FOR XMLSQL Server

2009-06-24 07:51:56

Hibernate重復(fù)

2013-11-28 09:41:36

云會(huì)計(jì)軟件CRM客戶關(guān)系管理

2023-11-27 11:51:13

CSS前端

2012-05-01 08:26:00

iOS

2011-08-24 09:15:36

SQL Server數(shù)FOR XML AUT

2013-11-04 10:51:49

2009-11-18 16:36:13

路由器參數(shù)設(shè)置

2010-03-01 14:40:00

Python RSS處

2010-06-10 17:30:58

Linux 測(cè)試軟件

2010-06-11 17:15:18

rsync重啟

2010-09-27 13:41:22

JVM內(nèi)存回收
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)