종달랩 종다리 이야기

iOS 화면전환 및 데이터 전송방식(비동기 방식)

Computer Science/Android&iOS
반응형

화면전환시 데이터를 주고받는 방식은 동기식, 비동기식으로 나눌 수 있습니다.

 

비동기식은 별도의 저장소를 두고 그곳에 데이터를 저장하고, 상호 데이터를 조회하는 방식입니다.

 

갑을 주고받는다기 보다는 글로벌한 곳에 데이터를 두고 상호참조하는 방식으로 이해하면 됩니다.

 

그러면 어디에 데이터를 저장하고 읽고, 쓰기를 진행하면 될까요.

 

1. AppDelegate를 이용한 접근

 

Swift의 모든 개체가 다 접근할 수 있는 AppDelegate class가 적합합니다.

 

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  
  var paramEmail: String?
  var paramUpdate: Bool?
  var param.....

여기에 변수를 정의합니다.

 

그러면 해당 데이터는 어떻게 접근할까요?

@IBAction func onSubmit(_ sender: Any){
  let ad = UIApplication.shared.delegate as? AppDelegate
  
  ad?.paramEmail = self.email.text
  ..

다음과 같이 UIAppliation에 접근해서 데이터를 바로 읽고, 쓰면 됩니다.

 

2. UserDefaults 객체를 이용한 방법

iOS에는 코코아 터치 프레임워크가 있습니다. iOS의 전통적인 프레임워크이고 swift에서도 사용이 가능합니다. 이 개체의 장점은 앱을 삭제하기 전까지는 반영구적으로 사용이 가능하다는 것입니다.

 

내부적으로 plist파일을 이용하여 값을 저장관리합니다. 기존에는 UserDefaults객체에 NSData, NSString, NSNumber와 같이 코코아 프레임워크에서 사용하는 데이타타입만 저장이 가능하지만, Swift에서는 기본 데이터타입도 저장관리가 가능해진 부분이 있습니다.

 

데이터에 읽고 쓰는 코드만으로 설명은 줄여도 될것 같습니다.

 

@IBAction func onSubmit(_ sender: Any){
  let ud = UserDefaults.standard
  
  ud.set(self.email.text, forKey: "email")
  ud.set(self.isUpdate.isOn, forKey: "isUpdate")
  ud.set(self.interval.value, forKey: "interval")
  
  self.presentingViewController?.dismiss(animated: true)
}

이 코드는 UserDefault에 데이터를 저장하게 됩니다.

 

overide func viewWillAppear(_ animated: Boole){
  let ud = UserDefaults.standard
  
  if let email = ud.string(forKey: "email") {
    resultEmail.text = email
  }
  
  let update = ud.bool(forKey: "isUpdate")
  resultUpdate.text = (update == true ? "Auto Update":"No Auto")
  
  let interval = ud.double(forKey: "interval")
  resultInterval.text = "\(Int(interval))"
}
반응형

iOS 화면전환 및 데이터 전송정리(Navigation controller)

Computer Science/Android&iOS
반응형

3. 네비게이션 컨트롤러 (Navigation Controller)

 

네비게이션 컨트롤러는 다양한 페이지들이 서로 연관이 있다면 호출하고 다시 되돌아오는데 기본적인 편리성을 제공하는 View Controller입니다.

기존에 present는 화면전화 및 복귀를 내가 직접 코딩해야 했고, 복귀할때 적어도 1개의 버튼을 만들어야 했지만, Navigation Controller는 이러한 부분을 자동화 해준다고 보면됩니다.

 

기존 오래된 개발자 입장에서는 이 부분을 어떻게 이해해야 하나 고민했지만, 역시 오래보면 익숙해진다고, 그냥 익숙해지면 됩니다.

 

Navigation Controller를 만들기 위해서는 처음부터 Navigation Controller를 화면에 추가하거나, 기존의 ViewController에 Navigation Controller를 embed시키면 됩니다. 말로 풀어쓰면 어렵고, 화면을 보고 설명합시다.

 

Library입니다.

Library에서 Navigation Controller를 추가합니다. 이러면 다음과 같이

Library에서 Navigation Controller를 선택
화면에 2개의 View Controller가 표시가 됩니다.

표시가 됩니다. 기본적으로 Table View Controller가 추가가 됩니다. 여기서 Table View Controller안에 컨트롤을 삭제하고 마치 새것처럼 작업해도 됩니다. 

 

저는 이 방법보다는 기존에 사용하던 View Controller가 있다면, 거기에 Navigation Controller를 추가하는게 더 맘에 편합니다. 이 방법은

ViewController를 선택하고 메뉴에서 다음과 같은 기능을 선택합니다.

그림에 자세히 설명이 되어있습니다. View Controller를 선택하고, Editor/Embed In/Navigation Controller를 선택하면 됩니다.

 

Navigation Controller 와 연결된 View Controller들은 Navigation Item이 자동으로 생성되고, 뒤로가기가 자동으로 생성됩니다.

그렇습니다. 이렇게 자동으로 뒤로가기가 생성이 됩니다. 물론 Navigation Controller와 연결을 시켜야 하지만요.

 

연결시키는 방법은 오른쪽 마우스 버튼으로 연결시키면 됩니다.

연결여부는 여기를 통해서 확인됩니다. Show 형태로 되었습니다. 이건 뭘 의미할까요.

사실 이러한 연결은 No coding형태입니다. Present에서도 이야기 드렸듯이 코딩으로 또는 No coding으로 구현이 가능합니다.

 

위에 마우스가 아닌 버튼에 함수를 설정하면 다음과 같을 것입니다. 

 

@IBAction func moveByNavy(_ sender: Any){
  guard let uvc = self.storyboard?.instantiaterViewController(withIdentifier: "SecondVC") else{
    return
  }
  
  self.navigationController?.pushViewController(uvc, animated: true)
}

navigationController의 pushViewController(_, animated:)를 이용한것입니다. 그래서 Show(e.g. Push)로 표시가 되는 것입니다.

 

뒤로가기 위해서는 자동으로 뒤로가는 버튼이 생성이 됩니다. 물론 이것도 우리는 코딩으로 처리할 수 있습니다.

 

@IBAction func back(_ sender: Any){
  self.navigationController?.popViewController(animated: true)
}

여기서 조심해야 할것은 NavigationController를 이용하게 되면 우리 의지와는 상관없이 NavigationItem이 추가로 생성되고, 왼쪽에 뒤로가기 버튼이 자동으로 생성된다는 것입니다. UI충돌을 막기 위해서는 View Controller의 왼쪽상단에 Navigation Item이 생성되는것을 고려한 UI디자인이 필요합니다.

반응형

iOS 화면전환 및 데이터 전송정리(present without coding)

Computer Science/Android&iOS
반응형

2. present를 이용하되 화면디자인만으로 처리하는 방법

 

기존 전통적인 개발자 입장에서 이 방법은 오히려 이해가 어려웠던 부분입니다. 마우스 오퍼레이팅만으로 코딩없이 화면을 호출한다는 개념이 말입니다.

익숙해지면 쓸만하지만, 생각보다 어려웠습니다. 

"만일 코드를 수정해야 하는데, 이걸 화면에서 뒤져서 찾아내야 하나.."

물론, 익숙해지기까지 적잖은 시간이 걸렸지만, 우선은 외우는거죠.

 

우선 ViewController를 만들고 버튼을 하나 만듭니다. 그리고, 이동할 ViewController도 하나 만들어야 합니다. 뭐, 화면을 그리듯이 만들면 됩니다. 

 

 

첫번째 ViewController이고, 위 하일라이트된 버튼에 대한 동작을 정의할것입니다.
두번째 ViewController 입니다. 여기로 이동합니다.

그러면 코디없이 어떻게 이 두개의 페이지를 버튼으로 연결시킬까요?

 

버튼을 선택하고 오른쪽 마우스버튼을 누르고 두번째 ViewController를 선택하고 나면 다음과 같은 팝업메뉴가 뜹니다.

여기서 저는 "Present Modally"를 선택했습니다. 각각의 멘뉴는 시간내서 한번씩 선택해보면 도움이 됩니다. 이렇게 선택하면

Segue의 도형모양이 어떤 동작을 선택했는지 알려줍니다.

이렇게 연결이 생기는데 이걸 "Segue"라고 합니다. "세그"라고 읽어버립시다. 이렇게 하면 코딩없이 해당 페이지가 보여지게 됩니다. 만일 페이지가 팝업처럼 보인다면 위 Segue를 선택하고

Presentation을 선택합니다.

Presentation을 "Full Screen"으로 선택하면 화면을 꽉 채워줍니다.

@IBAction func moveToBlueTest(_ sender: Any){
  let uvc = self.storyboard!.instantiateViewController(withIdentifier: "BluetoothTestVC")
  uvc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
  self.present(uvc, animated: true)
}

 

이러함 코드를 직접 작성하지 않아도 되는 것입니다. 

 

이제.. 화면을 복귀해야겠지요. 

 

present를 이용한것과 똑같다고 이야기 한것 기억하시고, 두번째 ViewController에서 "Close"버튼에 다음과 같은 코드를 작성합니다.

 

@IBAction func close(_ sender: Any){
  self.presentingViewController?.dismiss(animated: true)
}

예.. 이 버튼을 클릭하면 이제 화면을 dismiss하게 됩니다.

 

그런데, 화면표시를 아무 코딩없이 했는데, 화면닫기는 왜 코딩을 해야 하나 궁금할 수 있습니다. 이건 다음다음편에.. Unwind기법으로 소개합니다.

반응형

iOS 화면전환 및 데이터 전송정리(present)

Computer Science/Android&iOS
반응형

1. present 메소드 활용

 

ViewController를 생성하고 버튼도 하나 만드어 본다 (BlueTest)
두번째 ViewController를 만든다. 이때 해당 ViewController의 이름을 설정한다. "BluetoothTestVC"로 명명한다.
두번째 ViewController의 이름을 설정한다.

"BlueTest" 버튼을 클릭하면 동작할 함수를 다음과 같이 정의한다. 화면이동을 위한 첫번째 코드입니다. 물론 첫번째 ViewController를 위한 클래스는 정의해야 합니다.

 

@IBAction func moveToBlueTest(_ sender: Any){
  let uvc = self.storyboard!.instantiateViewController(withIdentifier: "BluetoothTestVC")
  uvc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
  self.present(uvc, animated: true)
}

첫번째 ViewController에서 다음과 같은 코드를 통해서 두번째 ViewController로 이동하게 됩니다.

 

두번째 ViewController에서 화면을 종료하기 위해서는 다음과 같은 코드를 작성합니다.

 

@IBAction func Close(_ sender: Any){
  self.presentingViewController?.dismiss(animated: true)
}

해당 코드에서는 자체적으로 종료하는 것이 아니라, presentingViewController(즉, 현재 이 페이지를 호출하게 해준 ViewController를 통해서 화면을 닫도록 요청해야 함)를 통해서 현재 ViewController를 종료하도록 합니다.

 

여기서 만일 다시 self.presnet() 함수를 사용하게 되면, 화면을 닫는 것이 아니라 새로운 화면을 하나 더 만들어서 쌓게 됩니다. 메모리가 불필요하게 낭비가 되겠죠. 반드시 화면을 종료한다고 생각하고 화면을 닫아(dismiss) 해야 합니다.

반응형