View Debugging in Xcode

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

Screen-Shot-2015-04-07-at-12.03.28-PM-280x500-2.png

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. Screenshot-1-2.png

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 Screenshot-2-315x500.png

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 Screenshot-3.gif

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

Screenshot-5-395x500.png

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 iw21s.jpg

Từ chỗ này view hiarachy như sau:

  1. UINavigationTransitionView: container view, tại đây việc transitions của Navigation Controller sẽ xảy ra.
  2. UIViewControllerWrapperView: wrapper view chứa thuộc tính view của viewcontroller
  3. UIView: top-level view của view controller, là thuộc tính view của view controller
  4. 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. Screen-Shot-2015-04-07-at-12.24.14-PM-425x500.png

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: Screenshot-6-404x500.png

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 Screen-Shot-2015-03-15-at-5.03.26-PM-700x136.png

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 Screen-Shot-2015-04-07-at-12.29.20-PM-395x500.png

More view options

Để hệ thống 3D trở lại như ban đầu chọn button như hình dưới 1ac4375e5b1d109ef454afebdacd17083ffc3c1c.png Sử dụng View Mode

wireframes.gif

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 Screenshot-12-310x500.png

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 Screenshot-14-225x500.png

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