View Debugging in Xcode
Bài đăng này đã không được cập nhật trong 3 năm
View Debugging in Xcode 6
Khi bạn phát triển ứng dụng, đôi khi chúng ta sẽ gặp bug với các views hay các constraint autolayout mà không hề đơn giản để tìm chúng trong code. Thay vì in các frames ra màn hình console hay phải cố gắng dùng đầu để hình dung nó thì bây giờ nhờ sự giúp đỡ của Xcode bạn có thể xem được toàn bộ các view và hệ thống cấp bậc của toàn bộ các view trong ứng dụng 1 cách trực quan dễ dàng. Trong bài hướng dẫn này tôi sẽ hướng dẫn cách sử dụng View Debugging 1 trong những tính năng tuyệt vời của Xcode.
Getting Started
Trong hướng dẫn này chúng ta sẽ sử dụng JSQMessagesViewController 1 thư viện Chat UI. Bạn có thể download tại đây https://github.com/jessesquires/JSQMessagesViewController Giải nén project, chạy lệnh pod install để cài đặt các thư viện cần thiết, sau đó mở project này lên build and run. Tap vào mục Push via storyboard, màn hình chat giữa Steve Jobs và Tim Cook sẽ được hiển thị ra
Trở lại Xcode, click vào Debug View Hierarchy trên thanh Debug bar, hoặc có thể truy cập qua menu Debug\View Debugging\Capture View Hierarchy.
Xcode lúc này sẽ dừng ứng dụng lại và màn hình Xcode sẽ hiển thị canvas vẽ ra toàn bộ cấu trúc phân cấp các views trong ứng dụng
Click và drag ảnh ta sẽ thấy được cấu trúc phân tầng các view dạng 3D, ta có thể dễ dàng quan sát được view nào nằm trước view nào
Exploring the View Hierarchy
Điều đặc trưng và phố biến trong mô hình 3D là bạn sẽ có cái nhìn từ phía bên trái khi bạn nhìn vào mô phỏng
Góc nhìn này rất hiệu quả giúp chúng ta hình dung được cách build các view của ứng dụng. Tuy nhiên nhìn vào đây ta thấy có rất nhiều view trống ở bottom (ngoài cùng bên trái) của stack. Vậy những màn hình này là gì? Click vào view ngoài cùng bên trái Xcode sẽ hightlight để ta nhận biết được view nào đã được chọn. Ta có thể quan sát ở Jump Bar (bên trên của canvas) hiển thị UIWindow là item cuối cùng.
Do app này chỉ sử dụng 1 window nên ta có thể cho rằng UIWindow tại điểm bắt đầu của Jump Bar chính là app key window hay nói cách khác chính là thuộc tính window của AppDelegate. Click vào view bên phải của window, nhìn vào Jump Bar ta sẽ thấy tên của nó là UILayerContainerView, class này thậm chí không phải là public class
Từ chỗ này view hiarachy như sau:
- UINavigationTransitionView: container view, tại đây việc transitions của Navigation Controller sẽ xảy ra.
- UIViewControllerWrapperView: wrapper view chứa thuộc tính view của viewcontroller
- UIView: top-level view của view controller, là thuộc tính view của view controller
- JSQMessagesCollectionView: collection view sử dụng bởi project này để hiển thị tất cả các messages. Focusing on Views of Intersest Trong việc debug view của project này, 4 views đầu tiên không thể hiện ý nghĩa gì nhiều, ta có thể loại bỏ nó khỏi canvas để dễ dàng quan sát các view khác. Nhìn vào thanh slider phía dưới của canvas như hình ảnh bên dưới.
Drag thumb bên trái từ từ sang phải 1 chút, ta sẽ thấy wireframe hiển thị app window biến mất khỏi canvas, nếu drag nhiều hơn 1 chút nữa UINavigationTransitionView cũng biến mất. Ta có thể drag thumb này thêm nữa để loại bỏ them các view không cần thiết. Drag thumb bên trái này để ẩn tất cả các view cha của JSQMessagesCollectionView, canvas bây giờ sẽ được hiển thị như sau:
Ta cũng có thể sử dụng các nút zoom phóng to thu nhỏ hay reset lại về kích thước ban đầu các view
Sử dụng spacing slider ở góc trái bên dưới canvas để thay đổi khoảng cách giữa các view giúp ta phân biệt các view dễ dàng hơn
More view options
Để hệ thống 3D trở lại như ban đầu chọn button như hình dưới Sử dụng View Mode
Inspecting View
Để có thể dễ dàng truy cập tới các View ta bấm tổ hợp phím Cmd + 6 để mở Debug Navigator
Xem thông tin các View chúng ta bấm cmd + option + 4 các thông tin view sẽ được hiển thị bên phải
Lấy thông tin các view ra màn hình Console
Nhấn chuột phải vào view cần in thông tin và chọn print
<UIView: 0x7fde6c475de0; frame = (0 0; 312 170); gestureRecognizers = <NSArray: 0x7fde6c484fe0>; layer = <CALayer: 0x7fde6c474750>>
| <JSQMessagesLabel: 0x7fde6c475eb0; baseClass = UILabel; frame = (0 0; 312 20); text = 'Today 10:58 PM'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476030>>
| <JSQMessagesLabel: 0x7fde6c476400; baseClass = UILabel; frame = (0 20; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476580>>
| <UIView: 0x7fde6c476b50; frame = (70 20; 210 150); autoresize = RM+BM; layer = <CALayer: 0x7fde6c474dd0>>
| | <UIImageView: 0x7fde6c482880; frame = (0 0; 210 150); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c476ae0>> - (null)
| <UIView: 0x7fde6c482da0; frame = (282 140; 30 30); autoresize = RM+BM; layer = <CALayer: 0x7fde6c482d00>>
| | <UIImageView: 0x7fde6c482e70; frame = (0 0; 30 30); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c482f70>> - (null)
| <JSQMessagesLabel: 0x7fde6c483390; baseClass = UILabel; frame = (0 170; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c483510>>
Conclusion
Đây là một số kĩ thuật debug view hiệu quả giúp ta có thể hiểu rõ hơn về hệ thống các view trong ứng dụng iOS, từ đó có cái nhìn sâu hơn về ứng dụng iOS giúp ta dễ dàng hơn khi viết ứng dụng đồng thời cũng có thể giúp ta debugg gỡ rối ứng dụng khi gặp lỗi về UI. Tài liệu tham khảo: https://www.raywenderlich.com/98356/view-debugging-in-xcode-6
All rights reserved