+3

Simple Make interface With Auto Layout

1. Mở đầu

Sau khi Steve Jobs ra đi. Người kế nhiệm ông, người vừa công bố mình là gay, Tim Cook, đã thực hiện rõ rệt sự ủng hộ của mình với thế giới thứ 3 bằng cách làm iPhone ngày càng to hơn, dài hơn với iPhone 6 (667x375) và iPhone 6 Plus (736x414). Và để đáp lại nó, các iOS developer lại phải gồng mình với bài toán "Làm sao để phục vụ cái to hơn, dài hơn đây". Kích cỡ và tỉ lệ khác biệt làm việc sử dụng "autosizing masks" như trước đây trở nên khó khăn hơn, chúng ta phải viết rất nhiều code để tùy biến lại giao diện. Tuy nhiên, thời thế xuất anh hùng, đi cùng với các khó khăn đó, Autolayout đã được ra đời như một cứu cánh thực sự.

2. Giới thiệu về Autolayout

Autolayout là một constraint-based layout system, nó cho phép chúng ta tạo ra các interface có thể tự thay đổi kích cỡ để phù hợp với sự thay đổi kích cỡ của màn hình. Việc này sẽ giúp chúng ta có thể dễ dàng tạo ra giao diện trực quan đúng như ý muốn mà không phải tốn công xét lại kích cỡ, cũng như vị trí cho các view mỗi khi thay đổi kích cỡ màn hình.

Công cụ cơ bản của Autolayout chính là các constraint. Mỗi constraint đại diện cho một quan hệ về mặt hình học giữa 2 view. Lấy ví dụ đơn giản như "view A cách view B 10 pixel về phía bên phải". Autolayout sẽ xác định vị trí và kích thước của các view dựa trên các mối quan hệ giữa chúng và các view xung quanh, chính là những thứ đã được thể hiện thông qua các constraint. Để dễ hình dung hơn, dưới đây là hình ảnh thể hiện mối quan hệ giữa các view thông qua các constraint Screen Shot 2015-10-25 at 11.37.17 PM.png

3 . Sử dụng Autolayout

Để dễ dàng hơn trong việc hiểu về autolayout, chúng ta sẽ làm 1 ví dụ nhỏ. Giả sử chúng ta đã có 1 ứng dụng nhỏ, chạy rất ổn ở iPhone 5S như thế này Screen Shot 2015-10-26 at 9.51.48 AM.png OK, chúng ta đã design màn hình này ở trên iPhone 5S (4inch) nên khi xuất ra iPhone5S sẽ không vấn đề gì, nhưng khi chạy lên iPhone6 (4.7 inch) hoặc iPhone 6Plus (5.5 inch) thì nó sẽ ra như này Screen Shot 2015-10-26 at 10.26.53 AM.png

Công việc của chúng ta, rất đơn giản, là sử dụng autolayout để fix cái này một cách tự động, thay vì xét lại tọa độ cho nó trong hàm viewWillLayoutSubviews

- Bước 1 : Phân tích yêu cầu theo khía cạnh hình học

Như đã giới thiệu ở mục 2, mỗi constraint đại diện cho một quan hệ về mặt hình học giữa 2 view, nên chúng ta cần phân tích yêu cầu của mình trên khía cạnh hình học, qua đó chuyển thành constraint một cách dễ dàng hơn.

Như chúng ta đã biết, mỗi view được xác định thông qua 4 yếu tố mà chúng ta vẫn gọi là CGRect (x, y, width, height). Tương tự như vậy, mỗi một view sẽ được xác định với tối thiểu là 4 constraint không tương đồng, để xác định được 1 view duy nhất .

Vì mối quan hệ giữa các view là tương đối, nên trong mọi trường hợp, chúng ta cần ít nhất là 1 view, luôn được fix cứng vị trí để làm mốc cho việc xác định vị trí của các view khác . Trong trường hợp này, để đơn giản, chúng ta sẽ lấy luôn view ở ngoài cùng làm mốc .

Lấy ví dụ với imageview

Với logo imageview, tôi muốn nó sẽ luôn ở giữa màn hình, và tất nhiên, tôi muốn nó to ra hết toàn bộ phần width. ==> Điều này sẽ tương đồng với

  • imageview cách lề trái superview = 0
  • imageview cách lề phải superview = 0
  • imageview.x cách center.x của superview = 0
  • imageview.y cách center.y của superview = 0

==> OK, bạn đã có 3 yếu tố để xác định vị trí của imageview là ở giữa màn hình (x và y), chiều rộng của imageview, và như đã nói ở trên, 3 thôi là chưa đủ . Việc không thể xác định chính xác height của view sẽ làm cho việc hiển thị view không được như mong muốn. Tôi sẽ demo luôn ở đây

** Bước 2 : Thực hiện việc setup constraint **

Theo phân tích ban đầu, chúng ta sẽ tạo constraint như sau

  • image view sẽ ở giữa màn hình ==> giữ control, kéo chuột từ imageview tới superview của nó, nhấn shift để chọn nhiều constraint. Chúng ta sẽ chọn Center Horizontally và Center Verically sau đó chọn Add Constraints. Screen Shot 2015-10-26 at 9.29.39 PM.png

Để hình dung rõ hơn việc chúng ta vừa làm, chọn View/ Utilities / Show Size Inspector hay đơn giản hơn là bấm vào đây Screen Shot 2015-10-26 at 9.23.50 PM.png Screen Shot 2015-10-26 at 9.34.29 PM.png Wow, việc setup các constraint đã trở nên trực quan hơn rất nhiều rồi .

  • Tiếp tục với việc set width, chọn Pin, chúng ta sẽ chọn phần leading và trailing của imageview bằng 0, hay nói cách khác, imageview sẽ luôn giãn ra sao cho phần đầu và phần cuối của nó chính bằng superview ( lưu ý ở đây hãy uncheck constrain to margins) Screen Shot 2015-10-26 at 9.37.29 PM.png

Để theo dõi việc add constraint sẽ ảnh hưởng ra sao tới view, Xcode đã cung cấp cho chúng ta một công cụ preview vô cùng trực quan Screen Shot 2015-10-26 at 9.46.02 PM.png Screen Shot 2015-10-26 at 9.46.16 PM.png Xét background color cho imageview, và không cần phải chạy app, chúng ta có thể thấy ngay vấn đề ở đâyScreen Shot 2015-10-26 at 9.52.39 PM.png

Mặc dù đã add 4 constraint, nhưng việc height của imageview không được xác định đã làm cho imageview không xuất hiện như mong đợi.

Chúng ta có thể theo dõi việc add thiếu constraint ở Document Outline Screen Shot 2015-10-27 at 8.05.20 AM.png Click vào mũi tên đỏ, và chúng ta sẽ thấy các constraint bị thiếu ở đây. Screen Shot 2015-10-27 at 8.08.06 AM.png

Tuy nhiên, với việc add thiếu height, mặc định height của view sẽ thành 600px nên chúng ta sẽ thấy thông báo màu vàng Screen Shot 2015-10-27 at 8.11.30 AM.png Điều này thông báo với chúng ta rằng, có thể sau khi chạy app, phần height của view sẽ bị thay đổi, không còn đúng như mong muốn của chúng ta

Để fix điều này, có 2 lựa chọn, 1- fix cứng height của imageview như ban đầu hoặc 2- height của imageview sẽ tăng theo tỉ lệ của width. Rõ ràng, lựa chọn thứ 2 sẽ đảm bảo tính thẩm mỹ tối đa cho bức ảnh. Giữ control+kéo chuột từ imageview tới chính nó, chọn Aspect Ratio Screen Shot 2015-10-26 at 10.12.12 PM.png Bây giờ, imageview đã được xuất hiện đúng như mong đợi (dance7)

Với việc xác định kích thước, cũng như vị trí của imageview, bây giờ, chúng ta có thể sử dụng imageview như một cột mốc cho các button còn lại. Tùy thuộc vào yêu cầu của bài toán mà chúng ta sẽ setup các constraint còn lại. Và đừng quên ngó qua phần preview để xem chúng ta đã tạo ra những gì (hoho)

** Thực hành - Thực hiện lại các bước trên với 2 button còn lại **

Thực hiện việc setup cho button "Staff List" như sau :

  • Cách đều 2 cạnh của superview 20 pixel
  • Thay đổi height của button theo sự thay đổi của width
  • button sẽ cách phần bottom của imageview 30 pixel

Thực hiện việc setup cho button "About us" như sau :

  • Không lẽ bạn còn phải đọc dòng này nữa sao (hoho)

Kết quả mong đợi : Screen Shot 2015-10-27 at 8.17.44 AM.png

Bạn có thể tham khảo thêm phần demo ở repo này https://github.com/quocnb/AutoLayoutResearch

4 . Tổng kết

Ở 3 mục trên, tôi đã giới thiệu sơ qua những khái niệm cơ bản nhất, để bạn có thể dễ dàng setup giao diện của mình tùy biến theo các kích cỡ màn hình khác nhau. Khi xem xong bài này, bạn sẽ thấy autolayout là rất dễ dàng. Giờ đây, bạn đã nắm chắc nó trong tay, sẵn sàng làm mọi việc với nó. Hãy thử nó với UITableviewCell nhé. Nếu bạn gặp khó khăn trong việc sử dụng nó với TableViewCell như "tôi có 1 cái cell, và label của nó thay đổi height theo text ở trong nó" ... hãy theo dõi phần 2 để cùng bàn luận nhé. Phần 2 sẽ là phần nói kỹ hơn về Constraint và việc sử dụng nó trong UITableViewCell, thứ mà chúng ta vẫn sử dụng rất nhiều trong mỗi project. Nếu bạn đã control mọi thứ, hãy chia sẻ cùng mọi người nhé, welcome 😄


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.