Một số kỹ thuật Passing Data giữa các View Controllers (Phần 1)

Trong lập trình ứng dụng iOS, việc sử dụng các kỹ thuật Passing Data để truyền dữ liệu qua lại giữa các View Controllers là những kỹ năng bắt buộc mà bất cứ iOS Developer nào cũng cần phải biết và sử dụng. Trong các dự án thực tế, tuỳ vào những trường hợp cụ thể, chúng ta sẽ sử dụng các kỹ thuật khác nhau để giải quyết vấn đề một cách phù hợp và hiệu quả. Hãy cùng tôi tìm hiểu một số kỹ thuật Passing Data cơ bản và thường xuyên được sử dụng thông qua nội dung bài viết dưới đây.

1. Passing data sử dụng Segue

Đây là kỹ thuật phổ biến nhất và thường xuyên được sử dụng để truyền tải dữ liệu thông qua 1 segue nối giữa 2 view controllers trên storyboard. Cả 2 view controllers đều riêng biệt và không có thông tin gì về nhau. Mối liên hệ duy nhất trong trường hợp này chính là 1 segue nối trực tiếp giữa chúng. Khi việc chuyển màn hình diễn ra và segue được thực thi, thì phương thức prepare(for segue: UIStoryboardSegue, sender: Any?) sẽ được gọi ở view controller gốc. Lúc này, segue với vai trò là tham số đầu vào cho phương thức trên, nó sẽ cho biết những gì sẽ được thực hiện từ controller gốc đến controller đích thông qua "cầu nối" segue.

struct Data {}

class SourceViewController: UIViewController {
    let data = Data()
	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
		if let destinationViewController = segue.destination as? DestinationViewController {
			destinationViewController.data = data
		}
	}
}

class DestinationViewController: UIViewController {
	var data: Data?
}

Lưu ý: Trong thực tế, chúng ta thường gặp trường hợp 1 view controller có nhiều segue đến các view controller khác nhau. Dó đó, chúng ta cần xác định đúng các segue để truyền các data tương ứng. Để làm được điều này, cần định nghĩa 1 identifier cho segue và khi khai báo phương thức prepare(for segue...) thì phải kiểm tra segue.identifier để xác định đúng segue và truyền chính xác data cho nó.

2. Passing data không sử dụng segue

Một số trường hợp, chúng ta không thể sử dụng segue để chuyển từ màn hình này sang màn hình khác như:

  • 2 màn hình nằm ở 2 storyboard khác nhau
  • chuyển tới màn hình tạo bởi file nib
  • các màn hình được khởi tạo hoàn toàn bằng code Trong trường hợp này, việc truyền dữ liệu từ view controller này sang view controller khác là rất rõ ràng, đơn giản.
class SourceViewController: UIViewController {
    let data = Data()
	func presentDestinationViewController() {
		let destinationViewController = DestinationViewController(nibName: "DestinationViewController", bundle: nil)
		destinationViewController.data = data
		present(destinationViewController, animated: true, completion: nil)
	}	
}

Như chúng ta thấy ở trên, việc khởi tạo view controller và truyền dữ liệu diễn ra đồng thời.

3. Passing data trở lại view cotroller trước đó thông qua unwind segue

Ở trên, chúng ta đã truyền dữ liệu "forward" từ VC1 -> VC2 thông qua segue, tiếp theo chúng ta sẽ truyền ngược lại data từ destination VC -> source VC thông qua unwind segue. Khi segue được thực thi, prepare(for segue...) được gọi ở source VC như thường lệ. Lúc này, chúng ta sẽ lưu data muốn gửi đi thông qua 1 property mà destination VC có thể truy cập và đọc được data.

class SourceViewController: UIViewController {
	var data: Data?
	
	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
		data = Data()
	}
}

Sau đó, unwind action được gọi ở destination VC. Lúc này, destination VC sẽ đọc dữ liệu được truyền từ property của source VC.

class DestinationViewController: UIViewController {
	@IBAction func unwind(_ segue: UIStoryboardSegue) {
		if let origin = segue.source as? SourceViewController {
			let data = origin.data
			// Do something with the data
		}
	}
}

Để có thể sử dụng Unwind segue bạn cần invoke unwind call. Có 2 cách để là điều này:

  1. Sử dụng code: self.performSegue(withIdentifier: "YourIdentifier", sender: self)
  2. Ở storyboard: Ở Source VC, Ctrl + drag từ nút Exit đến button sẽ thực hiện việc quay trở lại Destination VC, sau đó chọn Action Segue muốn thực hiện: unwind:

Trên đây, chúng ta đã cùng nhau tìm hiểu 3 kỹ thuật cơ bản, đơn giản để xử lý Passing Data giữa các View Controller. Ở phần tiếp theo, chúng ta sẽ tiếp tục tìm hiểu các kỹ thuật về Passing Data cũng thường xuyên được sử dụng trong lập trình iOS (Delegation, Closure,...).