[tvOS] 탭바와 SplitView 메뉴 열기/닫기 with RxTV
15742 단어 tvOSAdventCalendarRxSwiftSwift
이번에는 RxSwift를 사용하여
UITabBarController
와 UISplitViewController
메뉴의 열고 닫기를 구현해 보겠습니다.두 가지 모두 Interface Builder에서 쉽게 작성할 수 있는 표준 UI 구성요소로, iOS와 마찬가지로 컨테이너 뷰 컨트롤러의 구조를 기반으로 만들어졌습니다.
우선은
UITabBarController
와 UISplitViewController
의 열고 닫기를 프로그램으로 하기 위해서는 어떤 처리를 써야 하는지 확인합니다. 둘 다 솔직한 API가 없기 때문에 약간의 해킹이 필요했습니다.탭바 열기/닫기
탭 바에 대해서는 StackOverflow에 단편적으로 실려 있습니다만 그대로는 움직이지 않고, 결과 이런 형태에 침착했습니다.
extension UITabBarController {
func showTabBar() {
self.tabBar.alpha = 1
self.tabBar.isHidden = false
UIView.animate(
withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: UIViewAnimationOptions.curveEaseOut,
animations:
{
self.base.tabBar.frame.origin.y = 0
}, completion: { _ in
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
})
}
func hideTabBar() {
UIView.animate(
withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: UIViewAnimationOptions.curveEaseOut,
animations:
{
self.base.tabBar.frame.origin.y = -self.base.tabBar.bounds.height
}, completion: { _ in
self.tabBar.isHidden = true
self.tabBar.alpha = 0
if let focused = UIScreen.main.focusedView,
focused.isDescendant(of: self.base.tabBar) {
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
})
}
}
SplitView 열기/닫기
이쪽은 iOS에서도 비슷한 느낌이 되는 것 같네요.
extension UISplitViewController {
func hideMasterViewIfNeeded() {
if !_isMasterViewHidden { toggleMasterView() }
}
func showMasterViewIfNeeded() {
if _isMasterViewHidden { toggleMasterView() }
}
private func toggleMasterView() {
let barButtonItem = displayModeButtonItem
UIApplication.shared.sendAction(barButtonItem.action!,
to: barButtonItem.target,
from: nil,
for: nil)
}
private var _isMasterViewHidden: Bool {
return view.subviews.contains { $0.frame.origin.x < 0 }
}
}
열고 닫다
그리고는 열고 닫고 싶을 때에 위의 실장을 불러 주면 됩니다.
isTabBarHidden
.throttle(latest: true, scheduler: MainScheduler.instance)
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] isHidden in
if isHidden {
self?.tabBarController?.hideTabBar()
} else {
self?.tabBarController?.showTabBar()
}
})
.disposed(by: rx.disposeBag)
RxTV
위의 코드 그대로도 괜찮습니다만, RxSwift의 세계에서는 기본적으로는 bind만으로 끝나면 코드가 깨끗이 하므로, 정리합시다.
RxTV를 사용하면, 위와 같은 코드는 일절 서지 않고 Binder로서 구현하고 있다 rx.isMasterViewHidden
와 rx.isTabBarHidden
의 프로퍼티에 각각 bind 하는 것만으로 끝납니다.
htps : // 기주 b. 코 m / 0383 / RxTV
타이머로 자동 문처럼 해 보았습니다.
import RxSwift
import RxTV
import UIKit
class SplitViewController: UISplitViewController {
private var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let main = MainScheduler.instance
Observable<Int>.timer(1.0, period: 1.0, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: rx.isMasterViewHidden)
.disposed(by: disposeBag)
Observable<Int>.timer(1.2, period: 1.2, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: tabBarController!.rx.isTabBarHidden)
.disposed(by: disposeBag)
}
}
하는 것에 비하면, 대부분의 코드가 깨끗이 하고 있다고 생각합니다.
요약
탭 바와 SplitView 메뉴 자동 열고 닫기를 RxSwift와 RxTV로 구현해 보았습니다. RxTV는 그 밖에도 rx.didUpdateFocus
이나 rx.didUpdateFocus(match:)
라고 하는 편리 API를 제공하고 있으므로 좋으면 사용해 보세요.
tvOS Advent Calendar 2017 내일은 @m_유키오 에 의한 「tvOS 재입문」입니다!
Reference
이 문제에 관하여([tvOS] 탭바와 SplitView 메뉴 열기/닫기 with RxTV), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toshi0383/items/90ea2d72fc6230ed4b24
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
extension UITabBarController {
func showTabBar() {
self.tabBar.alpha = 1
self.tabBar.isHidden = false
UIView.animate(
withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: UIViewAnimationOptions.curveEaseOut,
animations:
{
self.base.tabBar.frame.origin.y = 0
}, completion: { _ in
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
})
}
func hideTabBar() {
UIView.animate(
withDuration: 0.5,
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: UIViewAnimationOptions.curveEaseOut,
animations:
{
self.base.tabBar.frame.origin.y = -self.base.tabBar.bounds.height
}, completion: { _ in
self.tabBar.isHidden = true
self.tabBar.alpha = 0
if let focused = UIScreen.main.focusedView,
focused.isDescendant(of: self.base.tabBar) {
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
})
}
}
이쪽은 iOS에서도 비슷한 느낌이 되는 것 같네요.
extension UISplitViewController {
func hideMasterViewIfNeeded() {
if !_isMasterViewHidden { toggleMasterView() }
}
func showMasterViewIfNeeded() {
if _isMasterViewHidden { toggleMasterView() }
}
private func toggleMasterView() {
let barButtonItem = displayModeButtonItem
UIApplication.shared.sendAction(barButtonItem.action!,
to: barButtonItem.target,
from: nil,
for: nil)
}
private var _isMasterViewHidden: Bool {
return view.subviews.contains { $0.frame.origin.x < 0 }
}
}
열고 닫다
그리고는 열고 닫고 싶을 때에 위의 실장을 불러 주면 됩니다.
isTabBarHidden
.throttle(latest: true, scheduler: MainScheduler.instance)
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] isHidden in
if isHidden {
self?.tabBarController?.hideTabBar()
} else {
self?.tabBarController?.showTabBar()
}
})
.disposed(by: rx.disposeBag)
RxTV
위의 코드 그대로도 괜찮습니다만, RxSwift의 세계에서는 기본적으로는 bind만으로 끝나면 코드가 깨끗이 하므로, 정리합시다.
RxTV를 사용하면, 위와 같은 코드는 일절 서지 않고 Binder로서 구현하고 있다 rx.isMasterViewHidden
와 rx.isTabBarHidden
의 프로퍼티에 각각 bind 하는 것만으로 끝납니다.
htps : // 기주 b. 코 m / 0383 / RxTV
타이머로 자동 문처럼 해 보았습니다.
import RxSwift
import RxTV
import UIKit
class SplitViewController: UISplitViewController {
private var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let main = MainScheduler.instance
Observable<Int>.timer(1.0, period: 1.0, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: rx.isMasterViewHidden)
.disposed(by: disposeBag)
Observable<Int>.timer(1.2, period: 1.2, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: tabBarController!.rx.isTabBarHidden)
.disposed(by: disposeBag)
}
}
하는 것에 비하면, 대부분의 코드가 깨끗이 하고 있다고 생각합니다.
요약
탭 바와 SplitView 메뉴 자동 열고 닫기를 RxSwift와 RxTV로 구현해 보았습니다. RxTV는 그 밖에도 rx.didUpdateFocus
이나 rx.didUpdateFocus(match:)
라고 하는 편리 API를 제공하고 있으므로 좋으면 사용해 보세요.
tvOS Advent Calendar 2017 내일은 @m_유키오 에 의한 「tvOS 재입문」입니다!
Reference
이 문제에 관하여([tvOS] 탭바와 SplitView 메뉴 열기/닫기 with RxTV), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toshi0383/items/90ea2d72fc6230ed4b24
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
isTabBarHidden
.throttle(latest: true, scheduler: MainScheduler.instance)
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] isHidden in
if isHidden {
self?.tabBarController?.hideTabBar()
} else {
self?.tabBarController?.showTabBar()
}
})
.disposed(by: rx.disposeBag)
위의 코드 그대로도 괜찮습니다만, RxSwift의 세계에서는 기본적으로는 bind만으로 끝나면 코드가 깨끗이 하므로, 정리합시다.
RxTV를 사용하면, 위와 같은 코드는 일절 서지 않고 Binder로서 구현하고 있다
rx.isMasterViewHidden
와 rx.isTabBarHidden
의 프로퍼티에 각각 bind 하는 것만으로 끝납니다.htps : // 기주 b. 코 m / 0383 / RxTV
타이머로 자동 문처럼 해 보았습니다.
import RxSwift
import RxTV
import UIKit
class SplitViewController: UISplitViewController {
private var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let main = MainScheduler.instance
Observable<Int>.timer(1.0, period: 1.0, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: rx.isMasterViewHidden)
.disposed(by: disposeBag)
Observable<Int>.timer(1.2, period: 1.2, scheduler: main)
.map { $0 % 2 == 0 }
.bind(to: tabBarController!.rx.isTabBarHidden)
.disposed(by: disposeBag)
}
}
하는 것에 비하면, 대부분의 코드가 깨끗이 하고 있다고 생각합니다.
요약
탭 바와 SplitView 메뉴 자동 열고 닫기를 RxSwift와 RxTV로 구현해 보았습니다. RxTV는 그 밖에도 rx.didUpdateFocus
이나 rx.didUpdateFocus(match:)
라고 하는 편리 API를 제공하고 있으므로 좋으면 사용해 보세요.
tvOS Advent Calendar 2017 내일은 @m_유키오 에 의한 「tvOS 재입문」입니다!
Reference
이 문제에 관하여([tvOS] 탭바와 SplitView 메뉴 열기/닫기 with RxTV), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toshi0383/items/90ea2d72fc6230ed4b24
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여([tvOS] 탭바와 SplitView 메뉴 열기/닫기 with RxTV), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/toshi0383/items/90ea2d72fc6230ed4b24텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)