Communication over long distances with NotificationCenter
What is notification center and how does it work?
The probelm of protocol-delegate pattern
- protocol-delegate 패턴은 어떤 뷰 컨트롤러과 가까이 있는 다른 뷰 컨트롤러 사이에서 커뮤니케이션을 할 때는 효과적이다.
- 그러나 멀리 있는 뷰 컨트롤러로 커뮤니케이션을 하려고 한다면, 출발하는 뷰 컨트롤러와 도착하는 뷰 컨트롤러 사이에 있는 모든 뷰 컨트롤러에 delegate를 정의해주어야 한다.
Notification Center (= Observer Pattern)
- Notification center를 이용하면 위와 같은 문제를 해결할 수 있다.
- Notification center는 어떤 뷰 컨트롤러가 broadcast message를 보낸다.
그러면 notificaton center를 이용해서 로그아웃 기능을 구현해보자.
Adding the logout button
일단 로그아웃을 위한 버튼을 만들자.
Hooking up Notification Center
*protocol-delegate 패턴을 사용해서 로그아웃 기능을 구현하려면 AccountSummaryViewController → MainViewController → AppDelegate 로 가는 모든 과정에서 delegate를 추가해주어야 한다.
-
Util 폴더에
NSNotificationName.swift
파일을 생성한다.import Foundation extension Notification.Name { static let logout = Notification.Name("Logout") }
Notification.Name
은 라디오 스테이션과 같은 역할을 해준다. -
AppDelegate에 이벤트를 등록한다.
private func registerForNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(didLogout), name: .logout, object: nil) }
- default:
NotificationCenter
의 싱글턴 인스턴스
- default:
-
AccountSummaryViewController
의logoutTapped
메소드에서 notification을 보내는 코드를 추가한다.extension AccountSummaryViewController { @objc func logoutTapped(sender: UIButton) { NotificationCenter.default.post(name: .logout, object: nil) } }
When not to use
🤔 protocol-delegate 패턴을 쓰지 말고 전부 Notification Center만 쓸 순 없는 걸까?
- 앱의 많은 부분에서 notification center를 사용하면 코드를 이해하기 어려워진다.
- 이벤트를 추적하기가 어려워진다.
- 이벤트들의 조합이 의도하지 않은 결과를 만들 수 있다.
protocol-delegate는 뷰 컨트롤러와 뷰 컨트롤러, 또는 앱의 다른 부분과 직접적으로 커뮤니케이션 할 수 있는 방법이기 때문에 이를 더 많이 선호한다.
Notification Center를 과도하게 사용하지 않도록 주의하자.
Showing the password
로그인 화면에서 비밀번호 text field 우측에 있는 👁 아이콘을 누르면 비밀번호를 표시하거나 가릴 수 있는 기능을 구현해보자.
-
Utils 폴더에서 UITextField+SecureToggle.swift
파일을 새로 만든다.
-
아래와 같이 코드를 작성한다.
import Foundation
import UIKit
let passwordToggleButton = UIButton(type: .custom)
extension UITextField {
func enablePasswordToggle() {
passwordToggleButton.setImage(UIImage(systemName: "eye.fill"), for: .normal)
passwordToggleButton.setImage(UIImage(systemName: "eye.slash.fill"), for: .selected)
passwordToggleButton.addTarget(self, action: #selector(togglePasswordView), for: .touchUpInside)
rightView = passwordToggleButton
rightViewMode = .always
}
@objc func togglePasswordView(_ sender: Any) {
isSecureTextEntry.toggle()
passwordToggleButton.isSelected.toggle()
}
}
- 👁 버튼을 위한
passwordToggleButton
을 선언한다.
- rightView, rightViewMode : 텍스트 필드의 우측에 👁 버튼이 보여지도록 하기 위한 설정
- toggle() : Bool 값을 반전시키는 스위프트 메소드
- 이 코드들은 UITextField의 extension 내에 있는 코드들이기 때문에
isSecureTextEntry
와 같은 프로퍼티들에 바로 접근할 수 있다.
-
LoginView
에서 enablePasswordToggle()
을 적용시킨다.
passwordTextField.enablePasswordToggle()
How to dynamically adjusting the font to fit the view
Utils 폴더에서 UITextField+SecureToggle.swift
파일을 새로 만든다.
아래와 같이 코드를 작성한다.
import Foundation
import UIKit
let passwordToggleButton = UIButton(type: .custom)
extension UITextField {
func enablePasswordToggle() {
passwordToggleButton.setImage(UIImage(systemName: "eye.fill"), for: .normal)
passwordToggleButton.setImage(UIImage(systemName: "eye.slash.fill"), for: .selected)
passwordToggleButton.addTarget(self, action: #selector(togglePasswordView), for: .touchUpInside)
rightView = passwordToggleButton
rightViewMode = .always
}
@objc func togglePasswordView(_ sender: Any) {
isSecureTextEntry.toggle()
passwordToggleButton.isSelected.toggle()
}
}
- 👁 버튼을 위한
passwordToggleButton
을 선언한다. - rightView, rightViewMode : 텍스트 필드의 우측에 👁 버튼이 보여지도록 하기 위한 설정
- toggle() : Bool 값을 반전시키는 스위프트 메소드
- 이 코드들은 UITextField의 extension 내에 있는 코드들이기 때문에
isSecureTextEntry
와 같은 프로퍼티들에 바로 접근할 수 있다.
LoginView
에서 enablePasswordToggle()
을 적용시킨다.
passwordTextField.enablePasswordToggle()
화면 크기가 작으면 label의 내용이 잘려서 나올 때가 있다. (iOS에서는 기본적으로 다 보여지지 않는 텍스트는 ...
로 표시해준다.)
실제 앱을 개발할 때 이런 문제가 발생하는 경우, 이를 해결하는 방법에는 세 가지가 있다.
- 화면 크기가 작은 디바이스는 지원하지 않는다고 명시하기
- 글자가 잘리는 것보다 모든 디바이스에서 폰트 크기를 통일하는 것에 중점 두기
- 폰트 크기를 동적으로 조절하기 → label이 view에서 가지는 너비를 기준으로
세 번째 방법은 adjustsFontSizeToFitWidth
프로퍼티를 이용해서 쉽게 적용할 수 있다.
// AccountSummaryCell.swift
nameLabel.adjustsFontSizeToFitWidth = true
balanceLabel.adjustsFontSizeToFitWidth = true
Author And Source
이 문제에 관하여(Communication over long distances with NotificationCenter), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@240-coding/Communication-over-long-distances-with-NotificationCenter저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)