โดยทางโปรแกรมกลับไปยัง ViewController ก่อนหน้าใน Swift


211

ฉันส่งผู้ใช้ไปยังหน้าเว็บด้วยการคลิกปุ่ม หน้านี้เป็นUITableViewController UITableViewController

ตอนนี้หากผู้ใช้แตะที่เซลล์ฉันต้องการผลักเขากลับไปที่หน้าก่อนหน้า

ฉันคิดถึงสิ่งที่ชอบ self.performSegue("back")....แต่ดูเหมือนจะเป็นความคิดที่ไม่ดี

วิธีที่ถูกต้องในการทำคืออะไร?


13
self.navigationController? .ViewViewControllerAnimated (จริง)
Kalpesh

คำตอบ:


526

สวิฟท์ 3:

หากคุณต้องการกลับไปที่ตัวควบคุมมุมมองก่อนหน้า

_ = navigationController?.popViewController(animated: true)

หากคุณต้องการกลับไปที่ตัวควบคุมมุมมองรูท

_ = navigationController?.popToRootViewController(animated: true)

1
ฉันจะส่งข้อมูลกลับไปที่หน้าก่อนหน้าตัวควบคุมได้อย่างไรเมื่อมีการแตะเซลล์ ถ้าเราใช้ระบบนำทางController? .PicViewControllerAnimated (จริง)
JDDelgado

4
@JDDelgado นี่คือวิธีที่คุณส่งข้อมูลกลับมาพร้อมกับผู้ใช้stackoverflow.com/questions/12561735//
Mohamad Kaakati

36
สำหรับ Swift 3 นั่นคือ.popViewController(animated: true)
Sasho

9
เพื่อปัดคำเตือนใด ๆ :_ = self.navigationController?.popToRootViewController(animated: true)
Andrew K

1
เราไม่สนใจค่าส่งคืน _ = เป็นแบบแผนสำหรับที่รวดเร็ว
Andrew K

53

Swift 3 , Swift 4

if movetoroot { 
    navigationController?.popToRootViewController(animated: true)
} else {
    navigationController?.popViewController(animated: true)
}

navigationController เป็นทางเลือกเนื่องจากอาจไม่มี


@Vyacheslva ฉันได้รับข้อผิดพลาด "การใช้ 'seft' โดยปริยายในการปิดใช้ 'ตัวเอง' เพื่อให้ความหมายการจับภาพที่ชัดเจน"
Sandip Subedi

@SandipSubedi ใช้[weak self]และself?.navigationController?.
Vyacheslav

สิ่งนี้มีประโยชน์ แต่ฉันต้องการส่งตัวแปรบางอย่างพร้อมการนำทาง แต่ตอนนี้ฉันไม่สามารถ - ฉันใช้ override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? แต่เมื่อฉันใช้สิ่งนี้ฉันไม่สามารถใช้สิ่งนั้นได้
Saeed Rahmatolahi

วิธีการเพิ่ม navigationController แล้ว?
25

@ user25 เพิ่ม? คุณหมายถึงอะไร
Vyacheslav

37

สวิฟท์ 3

ฉันอาจจะตอบช้า แต่สำหรับ 3 คุณสามารถทำอย่างนี้ได้:

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "< Back", style: .plain, target: self, action: #selector(backAction))

    // Do any additional setup if required.
}

func backAction(){
    //print("Back Button Clicked")
    dismiss(animated: true, completion: nil)
}

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

2
คำถามไม่ได้ถามว่าผู้ใช้มีตัวควบคุมการนำทางหรือไม่ นี่คือคำตอบที่ง่ายที่สุดและดีที่สุดสำหรับไม่มีตัวควบคุมทิศทาง นี่ควรเป็นคำตอบที่ได้รับการยอมรับจริงๆ
Droid Chris

Thanks Droid - สวัสดี ernestofndz คุณอาจพูดถูกว่า rootVC จะถูกไล่ออก แต่สิ่งนี้ไม่ได้เกิดขึ้นกับฉันมันแค่ยกเลิก currentVC ปัจจุบันฉันกำลังเพิ่มและลบรายการทางโปรแกรมและอาจไม่ใช่วิธีเดียวกัน ด้วยองค์ประกอบการเพิ่มปกติบนกระดานเรื่องราว .. แก้ไขความเข้าใจของฉันถ้าฉันผิด ... สำหรับ tableView หากผู้ใช้ต้องการส่งผ่านรายละเอียดไปยังมุมมองอื่นนี่เป็นอีกกรณีหนึ่งและไม่มีการเชื่อมโยงกับสิ่งที่ฉันโพสต์และจะเห็นด้วย 100% กับคุณ .. ที่ฉันเข้าใจว่าต้องใช้ปุ่มย้อนกลับในกรณีนี้ :)
Fullpower

บางทีคุณสามารถเพิ่มการแนะนำเล็ก ๆ น้อย ๆ .. เพราะมีอยู่แล้วยกเลิก & navigationController? .ViewViewController
marlonpya

dismiss(animated: true, completion: nil)ไม่ทำงานหลังจากการหมุน!
user924

31

สวิฟต์ 4

มีสองวิธีในการย้อนกลับ / กลับไปที่ ViewController ก่อนหน้า:

  1. กรณีแรก : ถ้าคุณใช้: self.navigationController?.pushViewController(yourViewController, animated: true) ในกรณีนี้คุณต้องใช้self.navigationController?.popViewController(animated: true)
  2. กรณีที่สอง : หากคุณใช้: self.present(yourViewController, animated: true, completion: nil) ในกรณีนี้คุณต้องใช้self.dismiss(animated: true, completion: nil)

ในกรณีแรกตรวจสอบให้แน่ใจว่าคุณได้ฝัง ViewController ของคุณไปยัง navigationController ในสตอรี่บอร์ดของคุณ


19

ในกรณีที่คุณนำเสนอ a UIViewControllerจากภายในUIViewControllerเช่น ..

// Main View Controller
self.present(otherViewController, animated: true)

เพียงเรียกใช้dismissฟังก์ชัน:

// Other View Controller
self.dismiss(animated: true)

self.dismiss(animated: true)- ไม่ทำงานหลังจากการหมุน
924

17

รวดเร็ว 5 ขึ้นไป

กรณีที่ 1: ใช้กับตัวควบคุมทิศทาง

self.navigationController?.popViewController(animated: true)

กรณีที่ 2: ใช้กับตัวควบคุมมุมมองปัจจุบัน

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

11

หาก Segue เป็นประเภท 'Show' หรือ 'Push' คุณสามารถเรียกใช้ "popViewController (animated: Bool)" บนอินสแตนซ์ของ UINavigationController หรือถ้า segue เป็น "ปัจจุบัน" แล้วเรียกว่า "เลิก (มีชีวิตชีวา: Bool, การทำให้สมบูรณ์: (() -> โมฆะ)?)" พร้อมกับตัวอย่างของ UIViewController


7

สำหรับ swift 3 คุณเพียงแค่ต้องเขียนบรรทัดของรหัสต่อไปนี้

_ = navigationController?.popViewController(animated: true)

2

ลองสิ่งนี้: สำหรับมุมมองก่อนหน้าใช้สิ่งนี้:

navigationController?.popViewController(animated: true)  

ป๊อปรูทใช้รหัสนี้:

navigationController?.popToRootViewController(animated: true) 

2

Swift 4.0 Xcode 10.0 พร้อม TabViewController เป็นมุมมองล่าสุด

หาก ViewController สุดท้ายของคุณ embebed ใน TabViewController รหัสด้านล่างจะส่งคุณไปที่ราก ...

navigationController?.popToRootViewController(animated: true)
navigationController?.popViewController(animated: true)

แต่ถ้าคุณต้องการกลับไปที่มุมมองสุดท้าย (นั่นอาจเป็น Tab1, Tab2 หรือมุมมอง Tab3 .. ) คุณต้องเขียนโค้ดด้านล่าง:

_ = self.navigationController?.popViewController(animated: true)

สิ่งนี้ใช้งานได้สำหรับฉันฉันใช้มุมมองหนึ่งใน TabView ของฉัน :)


1

สำหรับคำถามเกี่ยวกับวิธีการฝัง viewController ของคุณไปที่ navigationController ในกระดานเรื่องราว:

  1. เปิดสตอรี่บอร์ดของคุณที่ viewController อื่นตั้งอยู่
  2. แตะ viewController ที่คุณต้องการให้ระบบควบคุมการนำทางของคุณเริ่มต้น
  3. ที่ด้านบนของ Xcode ให้แตะ "ตัวแก้ไข"
  4. -> แตะฝัง
  5. -> แตะ "Navigation Controller

1

อันนี้ใช้ได้สำหรับฉัน (Swift UI)

struct DetailView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

  var body: some View {
      VStack {
        Text("This is the detail view")
        Button(action: {
          self.presentationMode.wrappedValue.dismiss()
        }) {
          Text("Back")
        }
      }
    }
}

0

ฉันทำอย่างนี้

func showAlert() {
    let alert = UIAlertController(title: "Thanks!", message: "We'll get back to you as soon as posible.", preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
        self.dismissView()
    }))

    self.present(alert, animated: true)
}

func dismissView() {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

0

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

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

คุณสามารถค้นหารายละเอียดเพิ่มเติมได้ในUnwind Segues ทีละขั้นตอนStep-by-Step วิธีอธิบายได้ดีกว่าในลิงค์เดิมรวมถึงวิธีส่งข้อมูลกลับ แต่ที่นี่ฉันจะอธิบายสั้น ๆ

1) ไปที่ปลายทาง (ไม่ใช่แหล่งกำเนิด) ดูคอนโทรลเลอร์และเพิ่มส่วนขยายที่ผ่อนคลาย:

    @IBAction func unwindToContact(_ unwindSegue: UIStoryboardSegue) {
        //let sourceViewController = unwindSegue.source
        // Use data from the view controller which initiated the unwind segue
    }

2) การลาก CTRL จากตัวควบคุมมุมมองของตัวเองไปที่ไอคอนทางออกในการควบคุมมุมมองแหล่งกำเนิด:

คลายจากตัวควบคุมมุมมอง

3) เลือกฟังก์ชั่นคลายที่คุณเพิ่งสร้างเมื่อไม่นานมานี้:

เลือกฟังก์ชั่นคลาย

4) เลือกทำต่อคลายและให้ชื่อ:

การตั้งชื่อคลายทำต่อ

5) ไปที่สถานที่ใด ๆ ของแหล่งกำเนิดมุมมองตัวควบคุมและเรียกส่วนต่อเนื่องผ่อนคลาย:

performSegue(withIdentifier: "unwindToContact", sender: self)

ฉันพบวิธีการจ่ายเงินจำนวนมากเมื่อการนำทางของคุณเริ่มซับซ้อน

ฉันหวังว่านี่จะช่วยให้ใครบางคน


-3

ฉันสามารถเปลี่ยนเส้นทางไปยังรูทเพจโดยการเขียนโค้ดใน "viewDidDisappear" ของคอนโทรลเลอร์ที่ใช้ระบบนำทาง

override func viewDidDisappear(_ animated: Bool) { self.navigationController?.popToRootViewController(animated: true) }


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