Unwind segues สำหรับอะไรและคุณใช้มันอย่างไร


584

iOS 6 และ Xcode 4.5 มีคุณสมบัติใหม่ที่เรียกว่า "Unwind Segue":

การแยกส่วนที่ไม่สะดวกสามารถอนุญาตให้เปลี่ยนไปใช้อินสแตนซ์ของฉากที่มีอยู่ในกระดานเรื่องราวได้

นอกเหนือจากรายการสั้น ๆ นี้ในบันทึกย่อประจำรุ่น Xcode 4.5 ตอนนี้ UIViewController ดูเหมือนจะมีวิธีการใหม่สองสามวิธี:

- (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

การแบ่งส่วนการผ่อนคลายทำงานอย่างไรและใช้เพื่ออะไรได้บ้าง?

คำตอบ:


1267

โดยสังเขป

เซกชั่นคลาย (บางครั้งเรียกว่าทางออกเซกเมนต์ ) สามารถใช้เพื่อนำทางกลับผ่านส่วนย่อยแบบผลักแบบโมดอลหรือแบบป๊อปโอเวอร์ (ราวกับว่าคุณโผล่รายการการนำทางจากแถบนำทางปิดป๊อปโอเวอร์หรือยกเลิกตัวควบคุมมุมมอง ยิ่งไปกว่านั้นคุณสามารถผ่อนคลายได้อย่างแท้จริงไม่เพียงแค่หนึ่งเดียวเท่านั้น แต่ยังมีชุดของส่วนขยายแบบพุช / โมดอล / ป๊อปโอเวอร์เช่น "ย้อนกลับ" หลายขั้นตอนในลำดับการนำทางของคุณด้วยการผ่อนคลายเพียงครั้งเดียว

เมื่อคุณทำการแยกส่วนคลายคุณต้องระบุการกระทำซึ่งเป็นวิธีการกระทำของตัวควบคุมมุมมองที่คุณต้องการคลาย

Objective-C:

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

สวิฟท์:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

ชื่อของวิธีการกระทำนี้จะใช้เมื่อคุณสร้างส่วนต่อเนื่องที่ผ่อนคลายในกระดานเรื่องราว นอกจากนี้วิธีการนี้เรียกว่าก่อนที่จะมีการดำเนินการผ่อนคลาย คุณสามารถรับตัวควบคุมมุมมองต้นฉบับจากUIStoryboardSegueพารามิเตอร์ที่ส่งผ่านเพื่อโต้ตอบกับตัวควบคุมมุมมองที่เริ่มต้น segue (เช่นเพื่อรับค่าคุณสมบัติของตัวควบคุมมุมมอง modal) ในแง่นี้วิธีการที่มีฟังก์ชั่นที่คล้ายกันเป็นวิธีการของprepareForSegue:UIViewController

iOS 8 UPDATE:ผ่อนคลาย segues ยังทำงานกับ iOS 8 segues การปรับตัวเช่นการแสดงและแสดงรายละเอียด

ตัวอย่าง

ให้เรามีกระดานเรื่องราวพร้อมตัวควบคุมการนำทางและตัวควบคุมลูกที่สาม:

ป้อนคำอธิบายรูปภาพที่นี่

จาก Green View Controller คุณสามารถคลาย (นำทางกลับ) ไปที่ Red View Controller จากสีฟ้าคุณสามารถผ่อนคลายเป็นสีเขียวหรือสีแดงผ่านสีเขียว ในการเปิดใช้งานการคลายคุณต้องเพิ่มวิธีการพิเศษลงในสีแดงและเขียวเช่นนี่คือวิธีการดำเนินการในสีแดง:

Objective-C:

@implementation RedViewController

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

@end

สวิฟท์:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

หลังจากเพิ่มวิธีการดำเนินการแล้วคุณสามารถกำหนดส่วนเสริมคลายในกระดานเรื่องราวโดยการลากตัวควบคุมไปที่ไอคอนออก ที่นี่เราต้องการคลายเป็นสีแดงจากสีเขียวเมื่อกดปุ่ม:

ป้อนคำอธิบายรูปภาพที่นี่

คุณต้องเลือกการกระทำที่กำหนดไว้ในตัวควบคุมมุมมองที่คุณต้องการผ่อนคลาย:

ป้อนคำอธิบายรูปภาพที่นี่

นอกจากนี้คุณยังสามารถผ่อนคลายไปที่ Red from Blue (ซึ่งอยู่ห่างออกไปสองก้าวในการนำทาง) กุญแจสำคัญคือการเลือกการดำเนินการผ่อนคลายที่ถูกต้อง

ก่อนที่จะดำเนินการต่อคลายผ่อนคลายวิธีการดำเนินการที่เรียกว่า ในตัวอย่างฉันนิยามคำว่าผ่อนปรนเป็นสีแดงจากทั้งสีเขียวและสีน้ำเงิน เราสามารถเข้าถึงแหล่งที่มาของการผ่อนคลายในวิธีการดำเนินการผ่านพารามิเตอร์ UIStoryboardSegue:

Objective-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!");
    }
}

สวิฟท์:

@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")
    }
}

การคลี่คลายยังทำงานผ่านการรวมกันของส่วนผลักดัน / กิริยา เช่นถ้าฉันเพิ่มตัวควบคุมมุมมองสีเหลืองอีกตัวด้วยชุดคำกริยาเราสามารถคลายตัวจากสีเหลืองไปจนถึงสีแดงได้ในขั้นตอนเดียว:

ป้อนคำอธิบายรูปภาพที่นี่

คลี่คลายจากรหัส

เมื่อคุณกำหนดเซกชั่นคลายโดยการลากตัวควบคุมบางอย่างไปที่สัญลักษณ์ออกของตัวควบคุมมุมมองเซกเมนต์ใหม่จะปรากฏใน Document Outline:

ป้อนคำอธิบายรูปภาพที่นี่

การเลือกทำต่อและไปที่ตัวตรวจสอบคุณสมบัติจะแสดงคุณสมบัติ "ตัวระบุ" ใช้สิ่งนี้เพื่อให้ตัวระบุที่ไม่ซ้ำกับส่วนย่อยของคุณ:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากนี้การทำต่อคลายสามารถทำได้จากรหัสเช่นเดียวกับส่วนอื่น ๆ :

Objective-C:

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

สวิฟท์:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)

12
+1 คำตอบที่ดี มันฟังดูดีจริงๆ แต่วิธีการที่ไม่เหมือนdismissViewControllerAnimated:completion:หรือpopViewControllerAnimated:บรรลุสิ่งเดียวกัน?
Sam Spencer

32
แน่นอนว่าพวกเขาสามารถ อย่างไรก็ตามหากคุณใช้สตอรีบอร์ดการแบ่งกลุ่มย่อยมักจะประสบความสำเร็จในสิ่งเดียวกันโดยใช้รหัสน้อยกว่ามาก ที่จริงตอนนี้คุณสามารถปิดตัวควบคุมมุมมองที่นำเสนอ modally โดยไม่ต้องเขียนรหัสใด ๆ แน่นอนว่ายังมีอีกหลายกรณีที่การปิดตัวควบคุมจากรหัสเป็นสิ่งที่ถูกต้อง
Imre Kelényi

7
ตรวจสอบให้แน่ใจว่าได้เพิ่มวิธีการกระทำของคุณลงในไฟล์ส่วนหัวมิฉะนั้นสตอรี่บอร์ดจะไม่ทราบ
Kyle C

17
ข้อได้เปรียบอีกข้อหนึ่งdismissViewControllerAnimated:completion:หรือมากกว่าpopViewControllerAnimated:นั้นคือวิธีการที่คุณเพิ่มลงในตัวควบคุมมุมมองที่คุณไม่ได้รับเชิญจะถูกเรียกใช้และเพื่อให้คุณมีวิธีที่ง่ายที่จะทราบว่าตัวควบคุมมุมมองที่นำเสนอนั้นเสร็จสิ้นแล้วโดยไม่ต้อง .
honus

8
ฉันขอแนะนำให้แก้ไขเล็กน้อยได้ไหม? ไม่ชัดเจน "ชัด" ที่คุณใส่ - (IBAction) relaxTRed: (UIStoryboardSegue *) relaxSegue ใน RedViewController.m และในทางกลับกันสิ่งนี้มีอยู่ทั่วไปในปุ่ม "ออก" สีเขียวสำหรับกระดานเรื่องราวใด ๆ คำตอบที่ยอดเยี่ยมและตอนนี้ฉันจะใช้สำหรับปัญหาอื่น ๆ ขอบคุณ!
John Ballinger

166

เท่าที่จะใช้การแบ่งส่วนผ่อนคลายในกระดานเรื่องราว ...

ขั้นตอนที่ 1)

ไปที่รหัสสำหรับตัวควบคุมมุมมองที่คุณต้องการคลายและเพิ่มสิ่งนี้:

Objective-C

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

อย่าลืมประกาศวิธีนี้ในไฟล์. h ของคุณใน Obj-C

รวดเร็ว

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

ขั้นตอนที่ 2)

ในกระดานเรื่องราวไปที่มุมมองที่คุณต้องการผ่อนคลายและเพียงลากส่วนต่อจากปุ่มของคุณหรือไอคอน "EXIT" สีส้มเล็ก ๆ ที่มุมบนขวาของมุมมองแหล่งที่มา

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้ควรมีตัวเลือกในการเชื่อมต่อกับ "- relaxToViewControllerNameHere"

เพียงเท่านี้เซคคิวของคุณจะคลายลงเมื่อกดปุ่ม


5
ฉันพบว่าด้วย Xcode 4.5 และก่อนหน้านี้จำเป็นต้องประกาศ IBAction ในส่วนหัว ฉันไม่รู้ว่านี่เป็นเรื่องจริงหรือไม่
สตีเวนฟิชเชอร์

2
มีวิธีการทำขั้นตอนที่ 2 ที่ไม่มีกระดานเรื่องราวหรือไม่ กระดานเรื่องราวของฉัน (ตัวสร้างส่วนต่อประสาน) สร้างความยุ่งเหยิงและมันจะไม่แสดงส่วนแบ่งที่ผ่อนคลาย (ข้อผิดพลาด xcode)
Van Du Tran

46

การแบ่งส่วนที่ไม่คุ้นเคยถูกใช้เพื่อ "ย้อนกลับ" ไปยังตัวควบคุมมุมมองบางตัวซึ่งคุณจะต้องใช้ตัวควบคุมมุมมอง "ปัจจุบัน" ผ่านตัวควบคุมหลายตัว

ลองนึกภาพคุณมีบางสิ่งบางอย่างMyNavControllerพร้อมกับAเป็นตัวควบคุมมุมมองรากของมัน Bตอนนี้คุณใช้ทำต่อการผลักดันเพื่อ ตอนนี้ตัวควบคุมการนำทางมี A และ B อยู่ในviewControllersอาร์เรย์และสามารถมองเห็นได้ B ตอนนี้คุณนำเสนออย่างCสุภาพ

ด้วยการผ่อนคลายส่วนแบ่งตอนนี้คุณสามารถ "ย้อนกลับ" จากCไปเป็นB(เช่นยกเลิกตัวควบคุมมุมมองที่นำเสนอแบบ modally) โดยทั่วไปแล้ว "เลิกทำ" คำสั่งกิริยา คุณสามารถผ่อนคลายไปจนถึงตัวควบคุมรูทวิวได้Aโดยยกเลิกการทำทั้งกิริยาช่วยและพุช

การแยกส่วนที่คลายออกทำให้ง่ายต่อการย้อนรอย ตัวอย่างเช่นก่อน iOS 6 การปฏิบัติที่ดีที่สุดสำหรับการไล่ที่นำเสนอมุมมองที่ควบคุมคือการตั้งค่าการควบคุมมุมมองการนำเสนอเป็นตัวแทนตัวควบคุมมุมมองที่นำเสนอแล้วเรียกวิธีการผู้รับมอบสิทธิ์ของคุณเองซึ่งก็ห้าม presentedViewController เสียงที่ยุ่งยากและซับซ้อน? มันเป็น นั่นเป็นเหตุผลว่าทำไมการแบ่งส่วนที่ผ่อนคลายเป็นสิ่งที่ดี


7
คุณสามารถโทรdismissViewController:animatedจากตัวควบคุมที่นำเสนอ คุณไม่จำเป็นต้องมอบหมาย แน่นอนว่าถ้าคุณต้องการส่งผ่านข้อมูลกลับคุณต้องมีการมอบหมายหรือวิธีอื่น
mxcl

3
ในขณะที่คุณสามารถโทรdismissViewController:animated:จากตัวควบคุมที่นำเสนอได้ "แนวปฏิบัติที่ดีที่สุด" ก็คือการเรียกวิธีการมอบหมายในตัวควบคุมการนำเสนอเพื่อทำสิ่งนั้นเพื่อคุณดังที่หยางกล่าวไว้
Chris Nolet

36

บางสิ่งที่ฉันไม่ได้กล่าวถึงในคำตอบอื่น ๆ ที่นี่คือวิธีที่คุณจัดการกับการคลี่คลายเมื่อคุณไม่รู้ว่าต้นกำเนิดเริ่มต้นมาจากไหนซึ่งสำหรับฉันก็เป็นกรณีการใช้งานที่สำคัญยิ่งกว่า ตัวอย่างเช่นสมมติว่าคุณมีตัวควบคุมมุมมองวิธีใช้ ( H ) ที่คุณแสดงแบบ Modally จากตัวควบคุมมุมมองที่แตกต่างกันสองตัว ( AและB ):

AH
BH

คุณตั้งค่าซีเควสคลายเพื่อให้คุณกลับไปที่ตัวควบคุมมุมมองที่ถูกต้องได้อย่างไร? คำตอบคือคุณประกาศการกระทำที่ผ่อนคลายในAและB ด้วยชื่อเดียวกันเช่น:

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

วิธีนี้การผ่อนคลายจะพบว่าตัวควบคุมมุมมอง ( AหรือB ) ใดเริ่มต้นการต่อและกลับไปที่มัน

กล่าวอีกนัยหนึ่งให้นึกถึงการกระทำที่ผ่อนคลายตามที่อธิบายว่ามาจากที่ไหนแทนที่จะทำตาม


2
ขอบคุณสำหรับข้อมูลนี้ฉันกำลังมองหานี้
Madhu

2
เป็นเรื่องที่ดีมากที่จะกล่าวถึงข้อมูลนี้เนื่องจากฉันใช้งานโซลูชันไปแล้วและไม่มีอะไรเกิดขึ้นจนกว่าฉันจะได้รับคำแนะนำที่นี่ขอบคุณมากสำหรับการสนับสนุนของคุณ
Amr Angry

นี่เป็นข้อมูลที่ยอดเยี่ยม! ขอบคุณมาก!
Dominique Vial

24

iOS ที่รวดเร็ว:

ขั้นตอนที่ 1: กำหนดวิธีนี้ในมุมมอง MASTER controller ของคุณ ที่คุณต้องการกลับไป:

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

    println("Called goToSideMenu: unwind action")

}

ขั้นตอนที่ 2: (กระดานเรื่องราว) คลิกขวาที่คุณกดปุ่ม SLAVE / CHILD EXIL และเลือก "goToSideMenu" เป็นการกระทำเพื่อเชื่อมต่อคุณปุ่มที่คุณจะคลิกเพื่อกลับไปหาคุณ MASTER controller view:

ป้อนคำอธิบายรูปภาพที่นี่ ขั้นตอนที่ 3: สร้างและเรียกใช้ ...


1

ตัวอย่างเช่นถ้าคุณนำทางจาก viewControllerB ไปยัง viewControllerA จากนั้นใน viewControllerA ของคุณด้านล่างตัวแทนจะโทรและข้อมูลจะแชร์

@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"
            }
            
        }

}
  • คลายตัวควบคุมมุมมองแหล่งที่มาของ Seague (คุณต้องเชื่อมต่อปุ่มออกไปยังไอคอนออกของ VC และเชื่อมต่อเพื่อคลายความรำคาญ:

ป้อนคำอธิบายรูปภาพที่นี่

  • ยกเลิกการเปิด Seague เสร็จสมบูรณ์ -> TextLabel ของ viewControllerA ถูกเปลี่ยนแล้ว

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.