스위프트 5
잘 매트 가격의 답변 은 데이터 전달에 완벽하게 적합하지만 최신 프로그래머 버전은 원래 게시물이 Objective-C에 있기 때문에 새로운 프로그래머가 새로운 구문 및 메소드 / 프레임 워크로 인해 도전을 끝내기 때문에 최신 Swift 버전에서 다시 작성하려고합니다.
View Controller간에 데이터 전달에 대한 여러 옵션이 있습니다.
- 네비게이션 컨트롤러 푸시 사용
- Segue 사용
- 델리게이트 사용
- 알림 관찰자 사용
- 블록 사용
최신 iOS 프레임 워크를 사용하여 Swift에서 그의 논리를 다시 작성하겠습니다.
네비게이션 컨트롤러 푸시를 통한 데이터 전달 : ViewControllerA에서 ViewControllerB로
1 단계. ViewControllerB에서 변수 선언
var isSomethingEnabled = false
2 단계. ViewControllerB의 ViewDidLoad 메소드에서 변수 인쇄
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue, navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
3 단계 . ViewController에서 탐색 컨트롤러를 통해 데이터를 전달
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
다음은 완전한 코드입니다.
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK:Passing Data through Navigation PushViewController
@IBAction func goToViewControllerB(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
//MARK: - Variable for Passing Data through Navigation push
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
}
Segue를 통한 데이터 전달 : ViewControllerA에서 ViewControllerB로
1 단계. ViewControllerA에서 ViewControllerB로 Segue를 생성하고 아래와 같이 스토리 보드에서 Identifier = showDetailSegue를 지정합니다.
2 단계. ViewControllerB에서 이름이 isSomethingEnabled 인 실행 파일을 선언하고 해당 값을 인쇄하십시오.
3 단계 . ViewController에서 Segue를 전달하는 동안 isSomethingEnabled의 값을 전달하십시오.
다음은 완전한 코드입니다.
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - - Passing Data through Segue - -
@IBAction func goToViewControllerBUsingSegue(_ sender: Any) {
performSegue(withIdentifier: "showDetailSegue", sender: nil)
}
//Segue Delegate Method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true//passing data
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
}
델리게이트를 통한 데이터 전달 : ViewControllerB에서 ViewControllerA로
1 단계. ViewControllerB 파일에서 클래스 외부의 프로토콜 ViewControllerBDelegate 선언
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
2 단계. ViewControllerB에서 델리게이트 변수 인스턴스 선언
var delegate: ViewControllerBDelegate?
3 단계. ViewControllerB의 viewDidLoad 메서드 내에서 델리게이트에 대한 데이터 보내기
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
4 단계. ViewControllerA에서 ViewControllerBDelegate 확인
class ViewControllerA: UIViewController, ViewControllerBDelegate {
// to do
}
5 단계. ViewControllerA에서 델리게이트를 구현할 것임을 확인
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self//confirming delegate
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
6 단계. ViewControllerA에서 데이터 수신을위한 델리게이트 메소드 구현
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
다음은 완전한 코드입니다.
ViewControllerA
import UIKit
class ViewControllerA: UIViewController, ViewControllerBDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
//Delegate method
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
@IBAction func goToViewControllerForDelegate(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
ViewControllerB
import UIKit
//Protocol decleare
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
class ViewControllerB: UIViewController {
var delegate: ViewControllerBDelegate?
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - Set Data for Passing Data through Delegate - - - - - -
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
}
}
알림 관찰자를 통한 데이터 전달 : ViewControllerB에서 ViewControllerA로
1 단계. ViewControllerB의 알림 관찰자에서 데이터 설정 및 게시
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
2 단계. ViewControllerA에서 알림 관찰자 추가
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
3 단계. ViewControllerA에서 알림 데이터 값 수신
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
다음은 완전한 코드입니다.
ViewControllerA
import UIKit
class ViewControllerA: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
// add observer in controller(s) where you want to receive data
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
}
//MARK: Method for receiving Data through Post Notification
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK:Set data for Passing Data through Post Notification
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
}
}
블록을 통한 데이터 전달 : ViewControllerB에서 ViewControllerA로
1 단계. ViewControllerB에서 블록 선언
var authorizationCompletionBlock : ((Bool)-> ())? = {_ in}
2 단계. ViewControllerB에서 블록으로 데이터 설정
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
3 단계. ViewControllerA에서 블록 데이터 수신
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
다음은 완전한 코드입니다.
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK:Method for receiving Data through Block
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
//MARK:Variable for Passing Data through Block
var authorizationCompletionBlock:((Bool)->())? = {_ in}
override func viewDidLoad() {
super.viewDidLoad()
//MARK:Set data for Passing Data through Block
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
}
}
내 GitHub에서 완전한 샘플 응용 프로그램을 찾을 수 있습니다 . 이것에 대한 질문이 있으면 알려주십시오.
@class ViewControllerB;
@protocol 정의보다 위에 배치해야 합니까? 그것없이 나는 줄에 ViewControllerB에 "예상 유형"오류가 발생합니다 : 선언- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
내에서@protocol