Phân biệt Unwind để làm gì và làm thế nào để bạn sử dụng chúng?


584

iOS 6 và Xcode 4.5 có một tính năng mới được gọi là "Unwind Segue":

Hủy bỏ phân biệt có thể cho phép chuyển sang các trường hợp hiện có của cảnh trong bảng phân cảnh

Ngoài mục ngắn gọn này trong ghi chú phát hành của Xcode 4.5, giờ đây UIViewControll dường như có một vài phương thức mới:

- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier

Làm thế nào để thư giãn thư giãn hoạt động và những gì họ có thể được sử dụng cho?

Câu trả lời:


1267

Tóm lại

Một segue thư giãn (đôi khi được gọi là segue thoát ) có thể được sử dụng để điều hướng trở lại thông qua các phân đoạn đẩy, phương thức hoặc popover (như khi bạn bật mục điều hướng từ thanh điều hướng, đóng cửa sổ bật lên hoặc loại bỏ bộ điều khiển xem được trình bày theo phương thức). Trên hết, bạn thực sự có thể thư giãn thông qua không chỉ một mà một loạt các phân đoạn đẩy / phương thức / popover, ví dụ: "quay lại" nhiều bước trong hệ thống phân cấp điều hướng của bạn với một hành động thư giãn duy nhất.

Khi bạn thực hiện một segue thư giãn, bạn cần chỉ định một hành động, đó là một phương thức hành động của bộ điều khiển xem mà bạn muốn thư giãn.

Mục tiêu-C:

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}

Nhanh:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

Tên của phương thức hành động này được sử dụng khi bạn tạo segue thư giãn trong bảng phân cảnh. Hơn nữa, phương pháp này được gọi ngay trước khi thực hiện phân tách thư giãn. Bạn có thể lấy bộ điều khiển chế độ xem nguồn từ UIStoryboardSeguetham số đã truyền để tương tác với bộ điều khiển khung nhìn đã khởi tạo segue (ví dụ: để lấy các giá trị thuộc tính của bộ điều khiển chế độ xem phương thức). Về mặt này, phương thức có chức năng tương tự như prepareForSegue:phương thức UIViewController.

Cập nhật iOS 8: Unwind segues cũng hoạt động với các phân biệt thích ứng của iOS 8, chẳng hạn như Hiển thịHiển thị chi tiết .

Một ví dụ

Hãy để chúng tôi có một bảng phân cảnh với bộ điều khiển điều hướng và ba bộ điều khiển xem con:

nhập mô tả hình ảnh ở đây

Từ Bộ điều khiển Chế độ xem Xanh, bạn có thể thư giãn (điều hướng trở lại) đến Bộ điều khiển Chế độ xem Đỏ. Từ Blue bạn có thể thư giãn sang Green hoặc Red qua Green. Để bật chức năng hủy kết nối, bạn phải thêm các phương thức hành động đặc biệt vào Đỏ và Xanh lục, ví dụ: đây là phương thức hành động trong Đỏ:

Mục tiêu-C:

@implementation RedViewController

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
}

@end

Nhanh:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

Sau khi phương thức hành động đã được thêm vào, bạn có thể xác định khoảng cách thư giãn trong bảng phân cảnh bằng cách kéo điều khiển vào biểu tượng Thoát. Ở đây chúng tôi muốn thư giãn sang Red from Green khi nhấn nút:

nhập mô tả hình ảnh ở đây

Bạn phải chọn hành động được xác định trong trình điều khiển xem bạn muốn thư giãn để:

nhập mô tả hình ảnh ở đây

Bạn cũng có thể thư giãn sang Red from Blue (cách "hai bước" trong ngăn xếp điều hướng). Điều quan trọng là chọn hành động thư giãn chính xác.

Trước khi phân tách thư giãn được thực hiện, phương thức hành động được gọi. Trong ví dụ này, tôi đã định nghĩa một segue thư giãn cho Red từ cả Green và Blue. Chúng ta có thể truy cập vào nguồn thư giãn trong phương thức hành động thông qua tham số UIStoryboardSegue:

Mục tiêu-C:

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
    UIViewController* sourceViewController = unwindSegue.sourceViewController;

    if ([sourceViewController isKindOfClass:[BlueViewController class]])
    {
        NSLog(@"Coming from BLUE!");
    }
    else if ([sourceViewController isKindOfClass:[GreenViewController class]])
    {
        NSLog(@"Coming from GREEN!");
    }
}

Nhanh:

@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) {
    if let blueViewController = unwindSegue.sourceViewController as? BlueViewController {
        println("Coming from BLUE")
    }
    else if let redViewController = unwindSegue.sourceViewController as? RedViewController {
        println("Coming from RED")
    }
}

Unwinding cũng hoạt động thông qua sự kết hợp của các phân đoạn đẩy / phương thức. Ví dụ: nếu tôi đã thêm một bộ điều khiển chế độ xem Màu vàng khác với một phân biệt phương thức, chúng ta có thể thư giãn từ Màu vàng trở lại màu Đỏ trong một bước duy nhất:

nhập mô tả hình ảnh ở đây

Unwinding từ Code

Khi bạn xác định một segue thư giãn bằng cách điều khiển - kéo một cái gì đó vào biểu tượng Thoát của bộ điều khiển xem, một segue mới xuất hiện trong Outline tài liệu:

nhập mô tả hình ảnh ở đây

Việc chọn segue và đi đến Thanh tra thuộc tính sẽ hiển thị thuộc tính "Định danh". Sử dụng công cụ này để cung cấp một mã định danh duy nhất cho segue của bạn:

nhập mô tả hình ảnh ở đây

Sau này, segue thư giãn có thể được thực hiện từ mã giống như bất kỳ segue nào khác:

Mục tiêu-C:

[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];

Nhanh:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)

12
+1 câu trả lời tuyệt vời. Chúng có vẻ rất hay, nhưng các phương pháp không thể dismissViewControllerAnimated:completion:hoặc popViewControllerAnimated:đạt được điều tương tự?
Sam Spencer

32
Chắc chắn họ có thể. Tuy nhiên, nếu bạn đang sử dụng bảng phân cảnh, các phân tách thư giãn thường có thể đạt được điều tương tự với mã ít hơn nhiều. Trên thực tế, bây giờ bạn có thể loại bỏ một trình điều khiển khung nhìn được trình bày mà không cần viết bất kỳ mã nào. Tất nhiên, vẫn còn nhiều trường hợp khi đóng bộ điều khiển từ mã là điều nên làm.
Imre Kelényi

7
Đảm bảo thêm phương thức hành động của bạn vào tệp tiêu đề của bạn nếu không Storyboard sẽ không biết.
Kyle C

17
Một ưu điểm khác là dismissViewControllerAnimated:completion:hoặc popViewControllerAnimated:phương thức bạn đã thêm vào trình điều khiển khung nhìn mà bạn không muốn gọi được gọi và do đó bạn có một cách dễ dàng để biết trình điều khiển khung nhìn được trình bày kết thúc mà không phải biến trình điều khiển khung nhìn trình bày thành đại diện của trình điều khiển khung nhìn được trình bày .
honus

8
Tôi có thể đề nghị một chỉnh sửa nhỏ? Rõ ràng là bạn không rõ ràng - (IBAction) relaxTRed: (UIStoryboardSegue *) Câu trả lời tuyệt vời và bây giờ tôi sẽ sử dụng điều này cho các vấn đề khác. Cảm ơn!
John Ballinger

166

Theo như cách sử dụng các khoảng cách thư giãn trong StoryBoard ...

Bước 1)

Chuyển đến mã cho trình điều khiển xem mà bạn muốn thư giãn và thêm phần này:

Mục tiêu-C

- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
    //nothing goes here
}

Hãy chắc chắn cũng khai báo phương thức này trong tệp .h của bạn trong Obj-C

Nhanh

@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
    //nothing goes here
}

Bước 2)

Trong bảng phân cảnh, đi đến chế độ xem mà bạn muốn thư giãn và chỉ cần kéo một biểu tượng từ nút của bạn hoặc bất cứ thứ gì lên biểu tượng "EXIT" màu cam nhỏ ở trên cùng bên phải của chế độ xem nguồn của bạn.

nhập mô tả hình ảnh ở đây

Bây giờ sẽ có một tùy chọn để kết nối với "- relaxToViewControllNameHere"

Thế là xong, segue của bạn sẽ thư giãn khi nhấn nút.


5
Tôi đã thấy rằng với Xcode 4.5 và trước đó cần phải khai báo IBAction trong tiêu đề. Tôi không biết nếu điều này vẫn đúng.
Steven Fisher

2
Có cách nào để thực hiện Bước 2 mà không cần bảng phân cảnh, tức là lập trình không? Bảng phân cảnh của tôi (trình xây dựng giao diện) đã bị rối và nó không hiển thị các phân tách thư giãn (lỗi xcode).
Văn Du Trần

46

Hủy bỏ các khoảng cách được sử dụng để "quay trở lại" với một số bộ điều khiển xem, từ đó, thông qua một số phân tách, bạn đã đến bộ điều khiển xem "hiện tại".

Hãy tưởng tượng bạn có một cái gì đó MyNavControllervới Abộ điều khiển xem gốc của nó. Bây giờ bạn sử dụng một segue đẩy để B. Bây giờ bộ điều khiển điều hướng có A và B trong viewControllersmảng của nó và B hiển thị. Bây giờ bạn trình bày một cách Cvừa phải.

Với segues thư giãn, bạn có thể tại Thư giãn "trở lại" từ Cđến B(tức là gạt bỏ các điều khiển xem modally giới), về cơ bản "hoàn tác" các segue phương thức. Bạn thậm chí có thể thư giãn hoàn toàn về bộ điều khiển xem gốc A, hoàn tác cả hai phương thức và phương thức đẩy.

Unwind segues làm cho nó dễ dàng để quay lại. Ví dụ: trước iOS 6, cách tốt nhất để loại bỏ các bộ điều khiển chế độ xem được trình bày là đặt trình điều khiển chế độ xem trình bày làm đại biểu của trình điều khiển chế độ xem được trình bày, sau đó gọi phương thức ủy nhiệm tùy chỉnh của bạn, sau đó loại bỏ trình điều khiển trình bày . Âm thanh cồng kềnh và phức tạp? Nó đã được. Đó là lý do tại sao thư giãn thư giãn là tốt đẹp.


7
Bạn có thể gọi dismissViewController:animatedtừ bộ điều khiển trình bày. Bạn không cần phải ủy thác điều đó. Tất nhiên nếu bạn cần truyền dữ liệu trở lại, thì bạn cần ủy quyền hoặc một số phương pháp khác.
mxcl

3
Mặc dù bạn có thể gọi dismissViewController:animated:từ bộ điều khiển được trình bày, "thực tế tốt nhất" thực sự là gọi một phương thức ủy nhiệm trên bộ điều khiển trình bày để làm điều đó cho bạn, như Yang đã đề cập.
Chris Nolet

36

Một điều mà tôi không thấy được đề cập trong các câu trả lời khác ở đây là cách bạn đối phó với việc giải quyết khi bạn không biết sự khác biệt ban đầu bắt nguồn từ đâu, mà đối với tôi là một trường hợp sử dụng thậm chí còn quan trọng hơn. Ví dụ: giả sử bạn có bộ điều khiển xem trợ giúp ( H ) mà bạn hiển thị vừa phải từ hai bộ điều khiển chế độ xem khác nhau ( AB ):

AH
BH

Làm thế nào để bạn thiết lập segue thư giãn để bạn quay lại bộ điều khiển xem chính xác? Câu trả lời là bạn tuyên bố một hành động thư giãn trong AB có cùng tên , ví dụ:

// put in AViewController.swift and BViewController.swift
@IBAction func unwindFromHelp(sender: UIStoryboardSegue) {
    // empty
}

Bằng cách này, thư giãn sẽ tìm thấy bất kỳ trình điều khiển xem ( A hoặc B ) nào khởi tạo segue và quay trở lại nó.

Nói cách khác, hãy nghĩ về hành động thư giãn như mô tả nơi mà sự khác biệt đến từ đâu , hơn là nơi nó sẽ đến.


2
Cảm ơn thông tin này, tôi đã tìm kiếm này.
Madhu

2
Thật tuyệt khi đề cập đến thông tin này vì tôi đã thực hiện giải pháp và không có gì xảy ra cho đến khi tôi nhận được tiền boa của bạn ở đây cảm ơn rất nhiều vì sự hỗ trợ của bạn
Amr Angry

Đây là một phần tuyệt vời của thông tin! Cảm ơn rât nhiều!
Dominique Vial

24

Swift iOS:

Bước 1: xác định phương thức này vào khung nhìn trình điều khiển MASTER của bạn. trong đó bạn muốn quay lại:

//pragma mark - Unwind Seques
@IBAction func goToSideMenu(segue: UIStoryboardSegue) {

    println("Called goToSideMenu: unwind action")

}

Bước 2: (StoryBoard) Nhấp chuột phải vào nút SLAVE / CHILD EXIT của bạn và chọn "goToSideMothy" Là hành động để kết nối với bạn Nút mà bạn sẽ nhấp để quay lại giao diện điều khiển MASTER của bạn:

nhập mô tả hình ảnh ở đây Bước 3: Xây dựng và chạy ...


1

Ví dụ: nếu bạn điều hướng từ viewControllB đến viewControllA thì trong viewControllA của bạn bên dưới đại biểu sẽ gọi và dữ liệu sẽ chia sẻ.

@IBAction func unWindSeague (_ sender : UIStoryboardSegue) {
        if sender.source is ViewControllerB  {
            if let _ = sender.source as? ViewControllerB {
                self.textLabel.text = "Came from B = B->A , B exited"
            }
            
        }

}
  • Điều khiển chế độ xem nguồn của Seawind (Bạn cần kết nối Nút thoát với biểu tượng thoát của VC và kết nối nó với relaxseague:

nhập mô tả hình ảnh ở đây

  • Đã hoàn thành việc hoàn thành Seague -> TextLabel của viewContoderA được thay đổi.

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.