Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 리펙토링
- swift documentation
- 리펙터링
- Xcode
- ribs
- Clean Code
- 애니메이션
- collectionview
- HIG
- SWIFT
- tableView
- ios
- uitableview
- Observable
- Refactoring
- 클린 코드
- map
- Protocol
- 리팩토링
- MVVM
- combine
- RxCocoa
- swiftUI
- UICollectionView
- Human interface guide
- clean architecture
- 스위프트
- rxswift
- UITextView
- uiscrollview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] OperationQueue, Operation 사용하여 NotificationView 구현 본문
iOS 응용 (swift)
[iOS - swift] OperationQueue, Operation 사용하여 NotificationView 구현
jake-kim 2022. 3. 21. 22:04
OperationQueue를 사용하여 Noti 구현
- NotificationView를 OperationQueue를 사용하여 보여지게 만들면, NotificationView 관련 작업을 cancel, suspend 할 수 있어서, 하나의 작업 단위로 Wrapping할 수 있는 장점이 존재
- NotificationView를 사용하는 입장에서는 단순히 NotificationView를 띄우는 행위를 `하나의 기능`이라고 보고 NotificationView를 몰라도 NotificationService.show()하여 노티뷰를 띄우는 기능을 사용하도록 하기 위함
- NotificationService 기능
protocol NotificationService {
func show(title: String, delay: UInt32, completion: @escaping () -> Void)
func cancel()
func suspend(enabled: Bool)
}
* OperationQueue 상세한 개념은 이전 포스팅 글 참고
구현 아이디어
- 노티 뷰로 사용될 NotificationView 구현
- NotificationService 구현 (NotificationView 인스턴스를 가지고 OperationQueue에 삽입하여 사용)
NotificationView 구현
- NotificationView 생성
- 해당 파일에서 NotificationView를 사용하고, 사용하는 입장에서 View의 존재를 몰라도 되므로 private으로 선언
// NotificationService.swift
import UIKit
private class NotificationView: UIView {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 22)
label.numberOfLines = 2
label.lineBreakMode = .byTruncatingTail
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(label)
return label
}()
init(title: String) {
super.init(frame: .zero)
self.backgroundColor = .systemGray3
self.titleLabel.text = title
NSLayoutConstraint.activate([
self.leftAnchor.constraint(equalTo: self.titleLabel.leftAnchor, constant: 12),
self.rightAnchor.constraint(equalTo: self.titleLabel.rightAnchor, constant: -12),
self.bottomAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: -12),
self.topAnchor.constraint(equalTo: self.titleLabel.topAnchor, constant: 12),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
- NotificationOperation 정의
- Operation을 상속받아서 main()부를 정의하여, 여기서 뷰 인스턴스를 만들고 애니메이션을 주어 노티뷰를 띄워주는 작업
- cancel 되었을 때, completion을 실행하지 않도록 self.isCancelled 값 이용
// NotificationService.swift
private class NotificationOperation: Operation {
private let title: String
private let delay: UInt32
private let completion: () -> Void
init(title: String, delay: UInt32, completion: @escaping () -> Void) {
self.title = title
self.delay = delay
self.completion = completion
}
override func main() {
sleep(self.delay)
DispatchQueue.main.async {
let notificationView = NotificationView(title: self.title)
notificationView.alpha = 0
notificationView.translatesAutoresizingMaskIntoConstraints = false
guard let window = UIApplication.shared.windows.first else { return }
window.addSubview(notificationView)
NSLayoutConstraint.activate([
notificationView.leftAnchor.constraint(equalTo: window.safeAreaLayoutGuide.leftAnchor),
notificationView.rightAnchor.constraint(equalTo: window.safeAreaLayoutGuide.rightAnchor),
notificationView.topAnchor.constraint(equalTo: window.safeAreaLayoutGuide.topAnchor),
notificationView.heightAnchor.constraint(equalToConstant: 80)
])
UIView.animate(
withDuration: 1,
delay: 0,
options: .curveEaseOut,
animations: { notificationView.alpha = 1 },
completion: { _ in
UIView.animate(
withDuration: 1,
delay: 1,
options: .curveEaseIn,
animations: { notificationView.alpha = 0 },
completion: { _ in
notificationView.removeFromSuperview()
if !self.isCancelled {
self.completion()
}
}
)
}
)
}
}
}
- NotificationService로 위에서 정의한 Operation을 사용하는 인터페이스 정의
- show: 노티 뷰를 보여주는 작업
- cancel: 노티 뷰 operation을 취소할 수 있어, 위에서 isCancelled를 추가하여 completion이 실행되지 않도록 하는 기능
- suspend: 노티 뷰 OperationQueue가 실행되지 않도록 막는 기능
protocol NotificationService {
func show(title: String, delay: UInt32, completion: @escaping () -> Void)
func cancel()
func suspend(enabled: Bool)
}
final class NotificationServiceImpl: NotificationService {
private let operationQueue = OperationQueue()
func show(title: String, delay: UInt32, completion: @escaping () -> Void) {
let operation = NotificationOperation(title: title, delay: delay, completion: completion)
self.operationQueue.addOperation(operation)
}
func cancel() {
self.operationQueue.cancelAllOperations()
}
func suspend(enabled: Bool) {
self.operationQueue.isSuspended = !enabled
}
}
사용하는 쪽
// ViewController.swift
private var notificationService: NotificationService?
override func viewDidLoad() {
super.viewDidLoad()
self.notificationService = NotificationServiceImpl()
}
@objc private func didTapNotiButton() {
self.notificationService?.show(title: "iOS앱 개발 알아가기", delay: 1) {
print("노티 완료")
}
}
'iOS 응용 (swift)' 카테고리의 다른 글
Comments