我正在创建一个日历应用程序,其中的一个屏幕具有横向视图和纵向视图。为简单起见,请以iOS苹果日历为例,其中横向视图为周视图(即与纵向视图完全不同)。
在我当前的代码中,我感觉到代码结构不好,效率可能降低。因为我基本上将用户电池和CPU与纵向视图同时用于周视图,即使不是每个人都使用周视图。 根据设备旋转情况实施不同的演示的更好的做法是什么?
我的尝试
(下面我还提供了一个代码示例,展示了我在代码中对这些尝试的实现。)
根据UIViewController
中设备方向的情况,会隔离并“弹出”两个viewWillTransition()
。尽管由于该方法在内存/ navigationStack中当前触发的所有视图控制器中触发而很快变得不合时宜,但如果您在右横向和左横向之间进行交换,则会导致导航堆栈中有更多viewControllers副本。
使用一个初始化的UIViewController
和两个UIView
子类,并通过委托协议模式与视图控制器通信。在viewWillTransition()
中,我只是根据设备的方向为两个UIViews
之间的alpha更改设置动画。
(我提供了两种简化来说明我的上述尝试,下面的示例中未包括诸如dataSource和UICollectionViews的委托方法之类的方法。)
尝试1:
class PortraitCalendar: UIViewController {
let portraitCalendarView : MonthCalendar = {
// Setup of my portrait calendar, it is a UICollectionView subclass.
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(portraitCalendarView)
// Additional setup..
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
performSegue(withIdentifier: "toLandscapeCalendar", sender: nil)
}
}
}
class LandscapeCalendar: UIViewController {
let landscapeView : LandscapeView = {
// Setup of the landscape view, a UICollectionView subclass.
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(landscapeView)
// Additional setup..
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isPortrait {
navigationController?.popViewController(animated: true)
}
}
}
尝试2:
class PortraitCalendar: UIViewController, LandscapeCalendarDelegate {
let portraitCalendarView : MonthCalendar = {
// Setup of my portrait calendar, it is a UICollectionView subclass.
}
// UIView subclass with a UICollectionView within it as a week calendar.
let landscapeCalendar = LandscapeView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(portraitCalendarView)
view.addSubview(landscapeCalendar)
landscapeCalendar.alpha = 0
portraitCalendarView.alpha = 1
// Constraints and additional setup as well of course.
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
navigationController?.isToolbarHidden = true
self.view.layoutIfNeeded()
landscapeCalendarDelegate?.splitCalendarViewWillAppear()
UIView.animate(withDuration: 0.1) {
self.portraitCalendarView.alpha = 0
self.landscapeCalendar.alpha = 1
}
} else {
self.portraitCalendarView.alpha = 1
self.landscapeCalendar.alpha = 0
}
}
}
感谢您阅读我的问题。
答案 0 :(得分:0)
我肯定会选择选项 2号。
这样,您就可以封装与日历有关的所有 logic ,例如在一个视图控制器中添加事件或显示事件,而无需在其他地方重新实现合理的逻辑(例如,其他视图具有横向模式的控制器)。对于不同的布局模式拥有两个视图并不容易维护,但是,如果这是显示两种模式之间差异的唯一方法,那确实是一个很好的解决方案。而且,与两个逻辑非常相似的视图控制器相比,维护起来要容易得多。