จะยกเลิก ViewController ใน Swift ได้อย่างไร


214

ฉันพยายามยกเลิก ViewController อย่างรวดเร็วด้วยการโทรdismissViewControllerหาIBAction

  @IBAction func cancel(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
}

@IBAction func done(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
}

ภาพสุ่มของ segue

ฉันเห็นข้อความ println ในเอาต์พุตคอนโซล แต่ ViewController ไม่เคยถูกไล่ออก มีปัญหาอะไร


2
คุณนำเสนอตัวควบคุมมุมมองได้อย่างไร
dasdom

ฉันทำแผนที่โดยตั้งค่า segue - "แสดง" ดูภาพหน้าจอที่แนบมา
rshankar

4
ลองใช้คำกริยา หากคุณใช้การพุชคุณควรยกเลิกด้วยวิธีป๊อปของตัวควบคุมทิศทาง
dasdom

คำตอบ:


415

จากภาพของคุณดูเหมือนว่าคุณได้นำเสนอ ViewController โดยใช้การพุช

dismissViewControllerAnimatedจะใช้ในการ ViewControllers ใกล้ที่นำเสนอโดยใช้คำกริยา

สวิฟท์ 2

navigationController.popViewControllerAnimated(true)

สวิฟต์ 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

6
คุณจะทำอย่างไรเพื่อทำส่วนย่อย 'แสดงรายละเอียด'
MoralCode

2
สำหรับSwift 2.2 navigationController!. PopViewControllerAnimated (จริง)
swiftBoy

7
สำหรับSwift 3 navigationController!. PopViewController (เคลื่อนไหว: จริง)
Alex Trott

175

ฉันมีทางออกสำหรับปัญหาของคุณ โปรดลองใช้รหัสนี้เพื่อยกเลิกตัวควบคุมมุมมองหากคุณนำเสนอมุมมองโดยใช้คำกริยา:

สวิฟท์ 3:

self.dismiss(animated: true, completion: nil)

หรือ

หากคุณแสดงมุมมองโดยใช้ "ดัน" ทำต่อ

self.navigationController?.popViewController(animated: true)

1
ขอบคุณ แต่ยังคงผลเดียวกันก็ไม่ได้ยกเลิก ViewController
rshankar

4
สิ่งนี้แตกต่างจากวิธีการที่ OP ใช้หรือไม่
dasdom

30
การสนทนาไม่มีประโยชน์หากคุณไม่ตอบคำถามของฉัน
dasdom

_ = self.navigationController? .popViewController (เคลื่อนไหว: จริง)
valexa

19

ถ้าคุณทำสิ่งนี้ฉันเดาว่าคุณอาจไม่ได้รับข้อความ println ในคอนโซล

@IBAction func cancel(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
   }
}

@IBAction func done(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
  }    
}

1
stackoverflow.com/questions/30840235/… . มีอะไรให้ช่วยไหมผมติดอยู่กับเรื่องนี้มานานแล้วและยังหาทางแก้ปัญหาไม่ได้เลย
ธีฮาออง

14

ใน Swift 3.0 ถึง 4.0 มันง่ายเหมือนกับพิมพ์ลงในฟังก์ชั่นของคุณ:

self.dismiss(animated: true, completion: nil)

หรือถ้าคุณอยู่ในตัวควบคุมทิศทางคุณสามารถ "ป๊อป" มัน:

self.navigationController?.popViewController(animated: true)

เลิกทำงานไม่ทำงานเพราะฉันใช้ pushViewController self.navigationController เท่านั้นหรือไม่? popViewController (เคลื่อนไหว: จริง) ทำงาน
iOS

13
  1. ฝังมุมมองที่คุณต้องการปิดใน NavigationController
  2. เพิ่ม BarButton ด้วย "Done" เป็น Identifier
  3. เรียกใช้ตัวช่วยแก้ไขโดยเลือกปุ่มเสร็จสิ้น
  4. สร้าง IBAction สำหรับปุ่มนี้
  5. เพิ่มบรรทัดนี้ในวงเล็บ:

    self.dismissViewControllerAnimated(true, completion: nil)

13

ใช้:

self.dismiss(animated: true, completion: nil)

แทน:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)

1
เพิ่ม ! ไปที่ navigationController และใช้งานได้สำหรับฉัน
Jason G

1
@naturalc: โปรดทราบว่าถ้า navigationController ไม่มีศูนย์และคุณใส่แอปจะทำงานผิดพลาด
jobima

8

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

self.presentingViewController?.dismiss(animated: true, completion: nil)

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


คุณบันทึกวันของฉัน
Shanu Singh

6

จากประสบการณ์ของฉันฉันเพิ่มวิธีที่จะยกเลิกฉันเป็นส่วนขยายไปยัง UIViewController:

extension UIViewController {
    func dismissMe(animated: Bool, completion: (()->())?) {
        var count = 0
        if let c = self.navigationController?.viewControllers.count {
            count = c
        }
        if count > 1 {
            self.navigationController?.popViewController(animated: animated)
            if let handler = completion {
                handler()
            }
        } else {
            dismiss(animated: animated, completion: completion)
        }
    }
}

ฉันจะเรียกวิธีการนี้เพื่อยกเลิกการดูคอนโทรลเลอร์ในUIViewControllerคลาสย่อยใด ๆ ตัวอย่างเช่นในการยกเลิกการกระทำ:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}

6

จากเอกสาร Apple :

ตัวควบคุมมุมมองการนำเสนอมีหน้าที่รับผิดชอบในการยกเลิกตัวควบคุมมุมมองที่นำเสนอ

ดังนั้นจึงเป็นการดีที่จะเรียกใช้วิธีการเลิกจ้างด้วยตนเอง

สิ่งที่คุณควรทำถ้าคุณนำเสนอมันเป็นคำสั่ง:

presentingViewController?.dismiss(animated: true, completion: nil)

4

อย่าสร้างส่วนย่อยใด ๆ จากยกเลิกหรือเสร็จสิ้นไปที่ VC อื่นและเขียนรหัสนี้เฉพาะปุ่มของคุณ @IBAction

@IBAction func cancel(sender: AnyObject) {
    dismiss(animated: false, completion: nil)
}

3

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

  1. เปิดกระดานเรื่องราว
  2. คลิกขวาที่ปุ่มยกเลิกและลากไปยังตัวควบคุมมุมมองก่อนหน้าซึ่งคุณต้องการย้ายกลับไปยังตัวควบคุมก่อนหน้า
  3. ตอนนี้ปล่อยคลิกขวาและคุณสามารถเห็นการกระทำบางอย่างที่ทำงานบนปุ่มยกเลิก
  4. ตอนนี้เลือกตัวเลือก "popover present" จากรายการ
  5. ตอนนี้คุณสามารถยกเลิกมุมมองปัจจุบันของคุณโดยคลิกที่ปุ่มยกเลิก

โปรดลองสิ่งนี้มันทำงานกับฉัน

วิธีที่สอง - การใช้งาน - navigationController.popViewControllerAnimated(true)

ขอให้โชคดี


stackoverflow.com/questions/30840235/… . มีอะไรให้ช่วยไหมผมติดอยู่กับเรื่องนี้มานานแล้วและยังหาทางแก้ปัญหาไม่ได้เลย
ธีฮาออง

3
นี่เป็นสิ่งที่ผิด คุณไม่เคยมองข้ามมุมมองที่คุณกำลังนำเสนอตัวควบคุมมุมมองใหม่ที่ด้านบนของมุมมองปัจจุบันแทนทำให้หน่วยความจำรั่ว นี่อาจเป็นสาเหตุให้แอปของคุณถูกปฏิเสธจาก app store
3366784

2

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


1

หากคุณกำลังนำเสนอ ViewController แบบ Modally และต้องการกลับไปที่รูท ViewController ให้ระมัดระวังในการยกเลิก ViewController ที่นำเสนอนี้ก่อนที่คุณจะกลับไปที่รูท ViewController มิฉะนั้น ViewController นี้จะไม่ถูกลบออกจากหน่วยความจำและทำให้หน่วยความจำรั่ว


1

ใน Swift 3.0

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

self.dismiss(animated: true, completion: nil)

1

ใน Swift 4.1 และ Xcode 9.4.1

ถ้าคุณใช้ pushViewController เพื่อนำเสนอตัวควบคุมมุมมองใหม่ให้ใช้สิ่งนี้

self.navigationController?.popViewController(animated: false)

คำตอบสำหรับการวางสำเนาอื่น ๆ
J. Doe

1

ลองสิ่งนี้:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}

วิธีการที่เรียกว่า "dismissViewController" ใช้เพียงพารามิเตอร์เดียวเท่านั้นซึ่งฉันคิดว่าดูเหมือนว่าจะยกเลิกการเคลื่อนไหวไปยังมุมมองก่อนหน้านี้เป็นวิธีที่ง่ายที่สุด
cassiodiego

0

รหัสนี้เขียนด้วยปุ่มเพื่อยกเลิก

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }

1
ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
DimaSan


0

หากคุณใช้วิธีการปัจจุบันใน parent VC คุณควรเรียกใช้ฟังก์ชั่นนี้เพื่อยกเลิกการใช้ VC ลูกนี้

self.dismiss(animated: true, completion: nil)

ถ้าคุณเรียก child VC โดยใช้วิธีการ push เพื่อยกเลิก child VC ให้ใช้สิ่งนี้

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