8

Tôi đang tạo GUI tùy chỉnh trên ứng dụng toàn cầu cho iPhone và iPad. Trên iPad nó phụ thuộc rất nhiều vào "sideViews" cho các tiện ích như thao tác nội dung, detailInformation và tương tự (nghĩ về một SplitView nâng cao). Từ một quan điểm trực quan, UIPresentationController mới là điểm cho phép tôi trình bày các "sideViews" (và không sử dụng dimmedView) và việc triển khai thực hiện đơn giản để xây dựng và duy trì, trong khi vẫn tích hợp độc đáo với bảng phân cảnh. Nhưng tôi cần để có thể thao tác nội dung của presentingViewController trong khi presentationViewController được hiển thị. Vì vậy, câu hỏi của tôi là, tôi có thể thiết lập userInteractionEnabled (hoặc tương tự) trên presentingViewController trong khi trình bày sideViews?Tôi có thể tạo UIPresentationController có userInteractionEnabled trên PresentingViewController không?

Trả lời

11

UIPresentationController chèn view chứa của nó như là một subview cửa sổ trên chế độ xem trình bày, do đó bất kỳ chạm bên ngoài được trình bày quan điểmbị mắc kẹt bởi quan điểm chứa và không bao giờ làm cho nó ở chế độ xem hiển thị.

Khắc phục là chèn chế độ xem trên chế độ xem vùng chứa đi qua các lần chạm đến chế độ xem trình bày. Bạn có thể sử dụng chế độ xem này làm chế độ xem mờ hoặc đặt backgroundColor thành [UIColor clearColor] để có chế độ xem hoàn toàn trong suốt. Đặt chế độ xem chuyển tiếp trong mã trình điều khiển bản trình bày của bạn.

@interface IVPasserView : UIView 

@property (strong, nonatomic) NSArray* passthroughViews; 

@end 

@implementation IVPasserView 

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    UIView* hit = [super hitTest:point withEvent:event]; 
    if (hit == self) 
     for (UIView* passthroughView in _passthroughViews) 
     { 
      hit = [passthroughView hitTest:[self convertPoint:point toView:passthroughView] 
           withEvent:event]; 
      if (hit) 
       break; 
     } 
    return hit; 
} 

@end 

Lưu ý: trong khi điều này vi phạm tinh thần của -[UIView hitTest:withEvent:] ở chỗ nó không trả lại một subview, điều này là trong thực tế như thế nào hệ thống tiêu chuẩn UIPopoverPresentationController xử lý nó. Nếu bạn đặt thuộc tính passthroughViews ở đó, chế độ xem vùng chứa sẽ phản hồi lại hitTest:withEvent: với chế độ xem qua lại, mặc dù chúng không phải là superview/Subview! Do đó, nó có khả năng tồn tại trong bản phát hành iOS tiếp theo.

+0

Giải pháp thú vị. Tôi chắc chắn cần phải thử. – jollyCocoa

+0

Đây là giải pháp tốt cho vấn đề chính xác trong tiêu đề câu hỏi. –

+0

Điều này thật tuyệt đẹp. –

2

Được rồi, do đó, có vẻ như ý tưởng của UIPresentationController KHÔNG có khả năng sử dụng nó như một SplitView nâng cao (hoặc ít nhất đó là kết luận hiện tại của tôi). Tôi đã quản lý để xây dựng một workaround mặc dù. Nếu có ai tìm cách xử lý tốt hơn, hãy cho tôi biết trong phần bình luận. Vì vậy, những gì tôi làm là tôi chèn xem của PresentingViewController trong transitionContext containerView (giống như hệ thống phân cấp container UIPresentationControllers containerView) tại Index 0. Điều này làm cho tôi có thể xử lý minh bạch touchEvents trong khung nhìn PresentingViewControllers. Nhưng nó loại bỏ chế độ xem PresentingViewControllers khỏi hệ thống phân cấp khung nhìn ban đầu của nó vì vậy tôi cần phải di chuyển nó trở lại khi bản trình bày bị loại bỏ. Nó có nghĩa là đưa khung nhìn trở lại khung nhìn của parentViewController nếu có, hoặc cửa sổ của ứng dụng, nếu presentingViewController là rootViewController của ứng dụng (có thể có các kịch bản khác nữa, nhưng điều này sẽ làm bây giờ).

Đây là tất cả được thực hiện trong animateTransition trong UIViewControllerAnimatedTransitioning.

Dưới đây là đoạn mã:

UIView.animateWithDuration(transitionDuration(transitionContext), 
     delay: 0.0, 
     usingSpringWithDamping: 1.0, 
     initialSpringVelocity: 0.5, 
     options: UIViewAnimationOptions.BeginFromCurrentState|UIViewAnimationOptions.AllowUserInteraction, 
     animations: {() -> Void in 
      animatingView.frame = finalFrame 
     }) { (finished:Bool) -> Void in 
      if !self.isPresentation { 
       if let parentViewController = backgroundVC.parentViewController { 
        parentViewController.view.addSubview(backgroundVC.view) 
       } 
       else if let window = (UIApplication.sharedApplication().delegate as! AppDelegate).window { 
        window.addSubview(backgroundVC.view) 
       } 
       fromView.removeFromSuperview() 
      } 
      else { 
       containerView.insertSubview(backgroundVC.view, atIndex: 0) 
      } 
      transitionContext.completeTransition(true) 
    } 
+1

Bạn đúng rằng trình điều khiển bản trình bày không phù hợp để thực hiện chế độ xem chia tách tùy chỉnh. Đối với điều đó, xem bộ điều khiển ngăn chặn có lẽ là một lựa chọn tốt hơn. –

1

Bản trình bày phương thức không phù hợp cho hoàn cảnh của bạn. Nó là tốt hơn để thực hiện kịch bản của bạn với bộ điều khiển xem container tùy chỉnh và ghi đè phương thức showDetailViewController:sender: để xử lý việc trình bày các bộ điều khiển xem bổ sung. Bạn có thể điều chỉnh phương thức này để hiển thị phương thức bộ điều khiển xem trên iPhone và bên phải trên iPad chẳng hạn.

Dưới đây là một đoạn trích từ Apple Documentation:

Trình bày Versus Hiển thị một View Controller

Lớp UIViewController cung cấp hai cách để hiển thị một bộ điều khiển xem :

Các showViewController: người gửi: và phương thức showDetailViewController: sender: cung cấp cách thích ứng và linh hoạt nhất để hiển thị các trình điều khiển xem . Những phương pháp này cho phép trình điều khiển xem trình bày quyết định cách tốt nhất để xử lý bản trình bày. Ví dụ, một khung nhìn container điều khiển có thể kết hợp bộ điều khiển xem như một đứa trẻ thay vì trình bày nó một cách bình thường. Hành vi mặc định hiển thị chế độ xem điều khiển một cách bình thường. Phương thức presentViewController: animated: completion: luôn hiển thị bộ điều khiển xem một cách bình thường. Trình điều khiển xem gọi phương thức này có thể không xử lý bài thuyết trình nhưng bản trình bày luôn là phương thức. Phương pháp này thích hợp với kiểu trình bày cho môi trường nhỏ gọn theo chiều ngang. Các phương thức hiển thị showViewController: sender: và showDetailViewController: sender: là cách ưu tiên để bắt đầu các bản trình bày. Bộ điều khiển chế độ xem có thể gọi cho chúng mà không biết bất kỳ điều gì về phần còn lại của cấu trúc bộ điều khiển chế độ xem hoặc vị trí của bộ điều khiển chế độ xem hiện tại trong cấu trúc phân cấp đó. Những phương pháp này cũng giúp bạn dễ dàng sử dụng lại các bộ điều khiển xem ở các phần khác nhau của ứng dụng mà không cần viết các đường dẫn mã có điều kiện .

+0

Xin chào Alexander! Cảm ơn câu trả lời của bạn, và lời xin lỗi của tôi cho phản ứng muộn. Điều này chắc chắn có vẻ như một giải pháp thú vị. Tôi sẽ xem nếu nó giải quyết vấn đề của tôi và nếu như vậy cung cấp cho bạn tín dụng cho nó. Upvote cho bây giờ cho một ý tưởng tốt. – jollyCocoa

Các vấn đề liên quan