Safe Area Layout Guide iOS 11 (Part 2)

Building Apps for iPhone X

Lời tựa

Trong bài viết về iOS 11: Safe Area Layout Guide và Large Titles tháng trước, mình đã đề cập qua về Safe Area Layout Guide, trong phần này mình sẽ điểm qua một số vấn đề chúng ta gặp phải đối với Safe Area Layout Guide trên chiếc iPhone X - một flagship của Apple năm 2017. Cùng nhìn qua hình ảnh của chiếc iPhone được mong đợi nhất năm 2017:

Vậy là sau 3 năm kể từ khi chiếc iphone 6 lần đầu tiên được ra mắt năm 2014, thiết kế của chiếc iPhone đã có sự thay đổi với độ phân giải 1125px × 2436px, kèm theo nó là Face ID thứ khiến chúng ta có một chiếc iPhone với cái sừng trâu (hay còn gọi là tai thỏ) ở màn hình. Kèm theo với thiết kế vô cực không viền màn hình, chúng ta có một màn hình OLED có cái tên mĩ miều "Super Retina Display" với bốn góc bo tròn. Chiếc iPhone với màn hình sừng trâu này là một thách thức khá lớn với các designer và iOS app developer khi họ phải thiết kế app sao cho phù hợp với một màn hình rất "dị như thế này". Đừng lo lắng, vì các lý do trên mà Apple đã giới thiệu với chúng ta một công cụ tuyệt vời đó là Safe Area Layout Guide, giải pháp để thay thế Top/Bottom Layout Guide. Chúng ta có thể tham khảo một số app mặc định của Apple trên iPhone X để xem các điểm mới trong thiết kế:

Chúng ta có Navigation Bar với large title, thanh search, và chúng hoạt động hoàn hảo dù cho màn hình nằm ngang hay dọc. Tham khảo các app mặc định của app là một cách tuyệt vời để chúng ta làm quen với các thiết kế mới của Apple và áp dụng chúng lên ứng dụng của mình.

Và sau đây mình xin điểm qua một số vấn đề mà các iOS app developer sẽ thường xuyên gặp phải và cách chúng ta khắc phục chúng:

Issue 1. View bị che bởi thanh Home Indicator

Cùng xét một ví dụ chúng ta có một app với màn hình hiển thị list các ảnh, khi chọn mỗi ảnh thì sẽ đi đến một màn hình hiển thị full screen từng ảnh, để chuyển sang ảnh tiếp theo chúng ta vuốt sang trái hoặc phải, bên dưới có một thanh page control để hiển thị ví trí của ảnh đang xem: Chúng ta có thể thấy thanh page control đang bị hiển thị một cách không chính xác, khi nó nằm quá gần với thanh Home Indicator, một đối tượng mới trên iPhone X dùng để thay thế nút Home vật lý. Nguyên nhân là do thanh Page control được relative với superview của nó thay vì relative với Safe Area Layout Guide. Việc chúng ta cần làm là sửa contraint bottom của page control view cho nó relative với cạnh bottom của Safe Area Layout Guide. Bước 1 Chúng ta cần enable Safe Area Layout Guide của file giao diện, nếu file giao diện này được bạn tạo từ trước đó với Top/Bottom Layout Guide thì đừng lo, hai thuộc tính này sẽ được tự động thay thế bằng Safe Area Layout Guide, và bạn chỉ việc sử dụng thôi.

Bước 2 Chọn bottom contraint của Page control và chọn để relative với Safe Area thay vì với Superview

Tiến hành re-build ứng dụng, chúng ta kết quả sẽ như sau:

Issue 2. UISearchController

a. SearchController nằm trên NavigationBar

Chúng ta chắc chắn sẽ gặp vấn đề này khi build các app cũ có sử dụng SearchController trên xcode 9, cùng so sánh nó với app mặc định là app Contacts

Có thể thấy màu của SearchBar và statusBar không được liền mạch như app Contacts. Và vấn đề này dường như nghiêm trọng hơn nếu chúng ta xoay ngang app ra:

Phần khung search thậm chí bị che mất bởi phần bo góc của màn hình, và nút "Cancel" cũng vậy. Có một điểm mới trên iOS 11 là searchController sẽ được quản lý bởi thuộc tính navigationItem.searchController, giúp cho nó hiển thị một cách chính xác hơn dự trên Safe Area Layout Guide. Mỗi khi muốn hiển thị UISearchController, thay vì gọi phương thức present(animated:) như đối với một UIViewController chúng ta làm như sau:

Tiến hành build và chạy lại ứng dụng, chúng ta thấy searchController giờ đã hoạt động hoàn hảo cả hai chiều portrait và lanscape:

b. UISearchController và UITableView

Trường hợp tiếp theo là khi chúng ta có một UITableView cùng với thanh searchBar bên dưới. Thông thường như đối với iOS trước đây cách chúng ta thường làm là đặt searchBar thành headerView của TableView. Tuy nhiên khi trên iOS 11 nó trông sẽ như thế này:

Thanh SearchBar với màu xám tạo cảm giác không liền mạch với NaivgationBar nằm bên trên nó, việc chúng ta cần làm gán searchController thành một thuộc tính của navigationItem.searchController và setActive = TRUE như sau:

Build và run, kết quả sẽ như sau:

Issue 3. UITableView Section

Với ví dụ trên, nếu chúng ta xoay ngang màn hình, mặc dùng thanh searchBar đã hiển thị một cách hoàn hảo, tuy nhiên hãy nhìn xem, thanh sectionHeader lại hiển thị có vẻ chưa ổn lắm. Lẽ ra màu của sectionHeader phải liền mạch ra đến sát rìa màn hình như app Contacts, tuy nhiên nó lại hiển thị như sau:

Cùng xem lại đoạn code xem có vấn đề gì đối với cách mà tôi đang cài đặt màu cho SeactionHeaderView

Để biết nguyên nhân vì sao chúng ta sẽ xem qua hình ảnh sau, để biết cách mà UITableView hiển thị như thế nào trên iPhoneX:

Có thể thấy trên iPhone X phần ContentView của Cell hay Header (màu xanh dương) sẽ nằm gọn trong vùng SafeArea đó là lý do vì sao SectionHeader lại hiển hị như vậy. May mắn thay, iOS 11 giới thiệu đến chúng ta một thuộc tính mới của UITableView có tên là insetsContentViewsToSafeArea, bạn có thể cài đặt cả bằng code hoặc bằng file giao diện. Giá trị mặc định của nó là TRUE, vì vậy nếu muốn contentView giờ sẽ chứa cả phần rìa màn hình bên ngoài Safe Are, chúng ta chỉ cần set giá trị insetsContentViewsToSafeArea bằng FALSE:

Lưu ý một chút, cho dù contentView giờ đã tràn ra hai cạnh màn hình, tuy nhiên vị trí của Layout Margins vẫn sẽ chỉ nằm trong vùng Safe Are, điều đó có nghĩa là các thuộc tính như Lable, Button, TextField, ... vẫn sẽ không bị phần "sừng trâu" che mất ở chế độ Lanscape nếu chúng ta relative chúng với Layout Margin.

Quay lại đoạn code trước đó, thay vì set màu cho giá trị headerView.contentView, chúng ta set màu cho giá trị headerView.backgroundView:

Build và run ứng dụng, Kết quả khi ở chế độ Lanscape sẽ hoạt động perfectly như sau:

Tổng Kết

Trên đây mình vừa điểm qua một số issue mà chúng ta thường gặp phải trên iPhone X khi thiết kế giao diện hoặc migrate giao diện từ Xcode version cũ hơn lên Xcode 9. Vì màn hình của iPhone X khá "dị", nên cách làm việc với nó không giống với cách chúng ta vẫn làm trên các màn hình thiết bị khác. Trên iOS mới này, việc chúng ta cần làm mỗi khi thiết kế giao diện app, đó là cần test một cách kĩ lưỡng từng màn hình, cả chế độ Portrait lẫn Lanscape trên iPhone X để tránh các lỗi cơ bản xảy ra. Find out more here: https://developer.apple.com/videos/wwdc2017/

Where go from here

Bạn có thể đọc thêm part 1 tại đây iOS 11: Safe Area Layout Guide và Large Titles