วิธีการดำเนินการ Unwind segue โดยทางโปรแกรม


307

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


33
ฉันพบว่านี่เป็นคำถามที่ถูกต้อง - ฉันมีด้วยตัวเอง คุณสามารถทำการแยกย่อยโดยทางโปรแกรมได้โดย 1. สร้าง segue แบบแมนนวล (ctrl-drag จาก File's Owner to Exit) 2. ตั้งชื่อใน IB จากนั้น 3. ทำ -performSegueWithIdentifier: sender: ในรหัสของคุณ
Yang Meyer

6
ไม่ควรปิด IMO ผู้ใช้ที่โหวตให้ปิดคำถามนี้แน่ใจว่าดูเหมือนจะไม่มีพื้นหลัง Obj-C / Cocoa Touch
LJ Wilson

Yang: คุณให้ชื่อมันยังไง?
sarfata

ฉันแค่ใช้ [การยกเลิกด้วยตนเอง ViewControllerAnimated: สำเร็จ YES: ไม่มี]; เพื่อออกจากโปรแกรม ฉันไม่รู้ว่ามันเป็นวิธีที่ถูกต้องหรือไม่
tangqiaoboy

1
sarfata: ก่อนอื่นคุณสร้าง "การคลายความเมื่อยล้าด้วยตนเอง" โดยใช้ Ctrl-ลากจาก viewcontroller ไปที่ "Exit" จากนั้นคุณสามารถค้นหาส่วนต่อขยายได้ในโครงร่างเอกสาร
huggie

คำตอบ:


283
  1. สร้าง segue แบบแมนนวล ( ctrl-drag จากเจ้าของไฟล์ถึง Exit)
  2. เลือกในเมนูตัวควบคุมด้านซ้ายด้านล่างปุ่ม EXIT สีเขียว

เลือกในเมนูควบคุมด้านล่างปุ่มสีเขียวออก

แทรกชื่อของ Segue เพื่อคลาย

จากนั้นให้- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.ระบุชื่อของคุณ


25
1) "เจ้าของไฟล์" - คำศัพท์เก่านั้นไม่ใช่เหรอ? มันใช้งานได้สำหรับฉันในการควบคุมการลากจากตัวควบคุมมุมมองไปที่ไอคอนออก 2) แม้ว่ามันควรจะชัดเจน Xcode กำลังค้นหาการประกาศในอินเทอร์เฟซของ IBAction ซึ่งใช้อาร์กิวเมนต์ UIStoryboardSegue การพูดคุยของ WWDC 2012 407 นั้นไม่ได้กล่าวถึงและไม่ได้วางรหัสนั้นโดยไม่ได้ไอคอน Exit ของฉันจะไม่ทำงานเมื่อลากการควบคุมไป 3) มันค่อนข้างดีที่ในตอนท้ายของลูกศรสีแดงขนาดใหญ่ของคุณในฟิลด์แอ็คชั่นคุณสามารถกดลูกศร "ไปที่นั่น"!
tobinjim

71
สำหรับทุกคนที่ชอบฉันยังคงมีปัญหาในการใช้คำตอบนี้ฉันได้รวบรวมคำแนะนำอย่างละเอียดยิ่งขึ้นและตัวอย่างใน repo นี้: github.com/bradley/iOSUnwindSegueProgramatically (ไม่พยายามโฆษณาตัวเองฉันเพิ่งกระแทกหัวกับกำแพง สำหรับชั่วโมงเกี่ยวกับเรื่องนี้และเห็นการตั้งค่าการทำงานที่ช่วยให้ผม).
bradleygriffith

3
@bradleygriffith คุณยอดเยี่ยมสุด ๆ อย่างน่าอัศจรรย์ ขอบคุณสำหรับคำแนะนำที่ดีเยี่ยม!
Eli_Rozen

7
@bradleygriffith ฉันหวังว่าคุณจะตอบคำถามนี้เพื่อที่ฉันจะได้ทำเครื่องหมายนั้นด้วย! การสนับสนุนที่ไม่ซ้ำกันของคุณคือการสร้างตัวควบคุมมุมมองที่ได้รับรหัสใด ไม่พบที่ใดก็ได้ ขอบคุณ!
Aaron Vegh

3
กุญแจสำคัญสำหรับทุกคนที่ยังคงนิ่งเฉยอยู่คือ IBACTION จำเป็นต้องอยู่ในตัวควบคุมมุมมองที่คุณกำลังกลับไปไม่ใช่ตัวที่คุณกำลังเข้าชม @bradleygriffith สะกดสิ่งนี้บน GitHub แต่ฉันไม่เห็นว่า พูดถึงทุกที่อื่น ส่วนนั้นมีความสำคัญ
Axeva

163

นี่คือคำตอบที่สมบูรณ์เกี่ยวกับ Objective C และ Swift:

1) สร้างส่วนIBActionต่อขยายที่ผ่อนคลายในตัวควบคุมมุมมองปลายทางของคุณ (ที่คุณต้องการทำต่อ) ทุกที่ในไฟล์การนำไปใช้งาน

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) ในตัวควบคุมมุมมองแหล่งที่มา (ตัวควบคุมที่คุณแยกจาก), ⌃ + ลากจาก "ชื่อกิจกรรม" เพื่อออก คุณควรเห็นชุดคลายเครียดที่สร้างขึ้นในขั้นตอนที่ 1 ในป๊อปอัพ (หากคุณไม่เห็นให้อ่านขั้นตอนที่หนึ่ง) เลือก relaxToContainerVC: จากป๊อปอัปหรือสิ่งที่คุณตั้งชื่อวิธีการเชื่อมต่อตัวควบคุมแหล่งที่มาของคุณกับ IBAction ผ่อนคลาย

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

3) เลือกทำต่อในโครงร่างเอกสารมุมมองควบคุมแหล่งที่มาของสตอรี่บอร์ด (มันจะแสดงอยู่ด้านล่าง) และให้มันระบุ

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

4) เรียกเซกชั่นคลายโดยใช้วิธีนี้จากคอนโทรลเลอร์มุมมองแหล่งที่มาแทนที่ชื่อเซสชั่นคลายของคุณ

// วัตถุประสงค์ C

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

// Swift

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

NB ใช้คุณสมบัติ sourceViewController ของพารามิเตอร์ segue บนวิธีคลายเพื่อเข้าถึงคุณสมบัติที่เปิดเผยใด ๆ บนตัวควบคุมแหล่งที่มา นอกจากนี้ให้สังเกตว่าเฟรมเวิร์กจัดการยกเลิกการควบคุมคอนโทรลเลอร์ หากคุณต้องการยืนยันวิธีการนี้ให้เพิ่มวิธีการ dealloc ให้กับตัวควบคุมแหล่งที่มาพร้อมกับข้อความบันทึกที่ควรเริ่มทำงานเมื่อมันถูกฆ่า หาก dealloc ไม่ทำงานคุณอาจมีรอบการกักกัน


2
โปรแกรมของฉันไม่ทำงานไม่ได้โทรเลย(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
xhg

2
วิธีการแก้ปัญหานี้ไม่ทำงานเมื่อตัวควบคุมมุมมองคุณไม่เต็มใจที่จะมีอยู่ในกระดานเรื่องราวของคุณเท่านั้น aka ไม่ได้มีการใช้งานที่กำหนดเองในการใช้รหัส
mnl

@mnl ไม่แน่ใจว่าสิ่งที่คุณพูด แต่มันทำงานร่วมกับฉากกระดานเรื่องราวหรือปลายปากกา หากคุณกำลังสร้างฉาก viewcontroller ในโค้ดคุณจะไม่ใช้วิธีการใด ๆ ที่ "คืน" IB ในชื่อของพวกเขาซึ่งเป็นโมฆะจริงๆเนื่องจากสิ่งเหล่านี้มีจุดประสงค์ในการสื่อสารระหว่างรหัสและ IB ที่อยู่ความคิดเห็นของคุณ?
smileBot

1
รูปภาพของคุณที่แสดงctrl+dragจากเป็นViewControllerถึงExitมีประโยชน์อย่างเหลือเชื่อ ขอบคุณ!
kbpontius

สำหรับการใช้งาน Swift 4.2: self.performSegue (withIdentifier: "relaxToVC", ผู้ส่ง: ตนเอง)
Reefwing

81

bradleygriffithคำตอบที่ดีมาก ฉันใช้ขั้นตอนที่ 10 และสร้างภาพหน้าจอเพื่อทำให้เข้าใจง่าย นี่คือภาพหน้าจอใน Xcode 6

  1. ควบคุมการลากจากไอคอนสีส้มไปยังไอคอน Exit สีแดงเพื่อสร้างความผ่อนคลายโดยไม่มีการกระทำ / ปุ่มใด ๆ ในมุมมอง

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

  1. จากนั้นเลือกunwind segueในแถบด้านข้าง:

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

  1. ตั้งค่าสตริงตัวระบุ Segue:

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

  1. เข้าถึงตัวระบุจากรหัส:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];

4
UIViewControllerแรกของทุกวิธีการในการคลี่คลายต้องรวมอยู่ภายใน จากนั้นโซลูชันของคุณจะทำงาน
Alex Cio

5
และคุณต้องตั้งค่าตัวระบุเป็นส่วนต่อท้ายใหม่นี้! อย่าลืมมัน
kraag22

1
เป็นไปได้หรือไม่ที่จะสร้างการเชื่อมต่อ "exit" ในคอนโทรลเลอร์มุมมองต้นฉบับโดยทางโปรแกรม?
Andrew Kirna

13

ผมใช้ซึ่งจะกลับมาให้คุณโทร[self dismissViewControllerAnimated: YES completion: nil];ViewController


6
ลาร์รีนั่นเป็นวิธีที่ถูกต้องสมบูรณ์แบบหากคุณต้องการกลับไปที่ตัวควบคุมมุมมองก่อนหน้านั่นคือวิธีที่นำเสนอสิ่งที่คุณกำลังออกไป คำถามเกิดขึ้นเพราะสิ่งใหม่ใน Xcode 4.5 คือความสามารถในการ "ผ่อนคลาย" จากตัวควบคุมมุมมองหนึ่งที่ใดที่หนึ่งในลำดับการนำเสนอไปยังตัวควบคุมมุมมองก่อนหน้านี้มาก ดู WWDC 2012 เซสชัน 407 สำหรับรายละเอียด
tobinjim

11

การอ้างอิงข้อความจากโน้ตด้านเทคนิคของ Apple ใน Unwind Segue: หากต้องการเพิ่มส่วนคลายที่จะถูกเรียกใช้โดยทางโปรแกรมให้ควบคุม + ลากจากไอคอนตัวควบคุมมุมมองของฉากไปที่ไอคอนทางออกจากนั้นเลือกการดำเนินการผ่อนคลายสำหรับส่วนต่อใหม่จากเมนูป๊อปอัป

ลิงก์ไปยังหมายเหตุด้านเทคนิค


6

คำตอบของ Vishal Chaudhry ทำงานได้สำหรับฉัน ฉันจะเพิ่มที่เพื่อทริกเกอร์ seque ด้วยตนเองโดยใช้:

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

จากภายใน ViewController คุณต้องเลือกซีเควสคลายภายใต้ฉากของ ViewController ในกระดานเรื่องราวและในมุมมองคุณสมบัติบน RHS ให้แน่ใจว่าฟิลด์ Indentifier มี namer ที่คุณอ้างถึงในรหัส ("mySegueName" ในตัวอย่างด้านบน )

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


3

โซลูชันที่เข้ากันได้ย้อนหลังที่จะทำงานกับเวอร์ชันก่อนหน้า ios6 สำหรับผู้ที่สนใจ:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}

2
การแยกส่วนที่ไม่สะดวกทำได้ดีกว่าการย้อนกลับไปยังคลาสที่แน่นอนในตัวควบคุมการนำทาง
Steve Moser

2

สวิฟท์ 4 :

1.สร้าง@IBActionด้วยส่วนควบคุมภายในที่คุณต้องการคลาย:

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2.ในกระดานเรื่องราวจากตัวควบคุมที่คุณต้องการแยก (คลาย) จาก ctrl + ลากจากเครื่องหมายควบคุมเพื่อออกจากระบบแล้วเลือกวิธีที่คุณสร้างไว้ก่อนหน้านี้:

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

3.ตอนนี้คุณสามารถสังเกตเห็นว่าในเอกสารเค้าร่างคุณมีบรรทัดใหม่ที่มีชื่อ "ผ่อนคลายต่อ .... " ตอนนี้คุณควรคลิกที่บรรทัดนี้และเปิดตัวตรวจสอบคุณลักษณะเพื่อตั้งค่าตัวระบุ (ในกรณีของฉันrelaxSegueIdentifier )

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

4.เกือบเสร็จแล้ว! ตอนนี้คุณต้องเปิดตัวควบคุมมุมมองที่คุณต้องการคลายและสร้างวิธีที่จะทำต่อ ตัวอย่างเช่นคุณสามารถเพิ่มปุ่มเชื่อมต่อกับรหัสด้วย@IBActionหลังจากนั้นในIBActionนี้ให้เพิ่มperfromSegue (withIdentifier: sender :) method:

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

นั่นคือทั้งหมดที่คุณต้องทำ!


เป็นไปได้หรือไม่ที่จะสร้างการเชื่อมต่อ "exit" ในคอนโทรลเลอร์มุมมองต้นฉบับโดยทางโปรแกรม?
Andrew Kirna

1

Swift 4.2, Xcode 10+

สำหรับผู้ที่สงสัยว่าจะทำอย่างไรกับ VC ที่ไม่ได้ตั้งค่าผ่านกระดานเรื่องราว (ผู้ที่มาที่คำถามนี้จากการค้นหา "โดยทางโปรแกรม" + "คลายความยุ่งยาก")

เนื่องจากคุณไม่สามารถตั้งค่าเซกเมนต์ผ่อนคลายโดยใช้วิธีการแก้ปัญหาเชิงโปรแกรมที่ง่ายที่สุด แต่เพียงผู้เดียวคือการโทร:

navigationController?.popToRootViewController(animated: true)

ซึ่งจะปรากฏตัวควบคุมมุมมองทั้งหมดบนสแต็กกลับไปยังตัวควบคุมรูทมุมมองของคุณ


หากต้องการแสดงเฉพาะตัวควบคุมมุมมองสูงสุดจากการนำทางสแตกให้ใช้:

navigationController?.popViewController(animated: true)


1
ที่มักจะมากกว่าที่คุณต้องการ - ป๊อปหนึ่งกลับทำเพียง: [self.navigationController popViewControllerAnimated: YES];
Andy Weinstein

แน่นอนฉันได้เพิ่มคำตอบของฉัน - ขอบคุณ @AndyWeinstein
10623169

0

FYI: ในการที่คำตอบของ @ Vadim จะทำงานร่วมกับการดำเนินการผ่อนคลายแบบแมนนวลที่เรียกจากภายใน View Controller คุณต้องวางคำสั่ง:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

ภายในเมธอด class overriden viewDidAppear จะเป็นดังนี้:

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

หากคุณใส่ไว้ในวิธีการอื่นของ ViewController เช่นviewDidLoadหรือviewWillAppearมันจะถูกละเว้น


3
ผิดแน่นอน โทร performSegueWithIdentifier จากทุกที่ที่คุณต้องการ
smileBot

สิ่งนี้จะไม่เป็นการผ่อนคลายต่อเนื่องเมื่อมุมมองโหลดหรือไม่ แทนที่จะแสดงเมื่อคุณต้องการตัวอย่างเช่นหลังจากกดปุ่ม
Pahnev

@Pahnev ใช่ ฉันไม่รู้ว่าคำตอบนี้จะได้ upvotes อย่างไร การโทรperformSegueWithIdentfierทำสิ่งนั้นอย่างแน่นอน: ทำการส่งสัญญาณจาก ViewController หนึ่งไปยังอีกที่หนึ่ง
ezcoding

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