patternswiftMinor
UISegmentedControl with view-animation
Viewed 0 times
withanimationviewuisegmentedcontrol
Problem
I have create a
```
import UIKit;
class ViewLikes:UIViewController {
var innerViews:[UIViewController] = [UIViewController]()
var currentIndex:Int = 0;
var centerView:UIViewController = UIViewController()
override func viewDidLoad() {
super.viewDidLoad()
title = "some title";
var view1:UIViewController = UIViewController()
var lab1:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab1.center = CGPointMake(160, 284)
lab1.textAlignment = NSTextAlignment.Center
lab1.text = "I'am a label1"
view1.view.addSubview(lab1)
var view2:UIViewController = UIViewController()
var lab2:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab2.center = CGPointMake(160, 284)
lab2.textAlignment = NSTextAlignment.Center
lab2.text = "I'am a label2"
view2.view.addSubview(lab2)
var view3:UIViewController = UIViewController()
var lab3:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab3.center = CGPointMake(160, 284)
lab3.textAlignment = NSTextAlignment.Center
lab3.text = "I'am a label3"
view3.view.addSubview(lab3)
innerViews.append(view1)
innerViews.append(view2)
innerViews.append(view3)
var segmentControl:UISegmentedControl = UISegmentedControl(items:["blah", "blah1", "blah2"]);
segmentControl.selectedSegmentIndex = currentIndex;
segmentControl.addTarget(self, action:"segmentSwitch:" , forControlEvents:UIControlEvents.ValueChanged )
segmentControl.setTranslatesAutoresizingMaskIntoConstraints(false)
self.centerView.view.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(segmentControl)
UISegmentedControl and a view under it. The view under contains all a view for each segment. I am doing an animation when the segment is changing.- Is a center view that contains all subviews the right approach?
- Is the animation is correctly done (this is my first animation in swift) or is there a better way to achieve that effect?
```
import UIKit;
class ViewLikes:UIViewController {
var innerViews:[UIViewController] = [UIViewController]()
var currentIndex:Int = 0;
var centerView:UIViewController = UIViewController()
override func viewDidLoad() {
super.viewDidLoad()
title = "some title";
var view1:UIViewController = UIViewController()
var lab1:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab1.center = CGPointMake(160, 284)
lab1.textAlignment = NSTextAlignment.Center
lab1.text = "I'am a label1"
view1.view.addSubview(lab1)
var view2:UIViewController = UIViewController()
var lab2:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab2.center = CGPointMake(160, 284)
lab2.textAlignment = NSTextAlignment.Center
lab2.text = "I'am a label2"
view2.view.addSubview(lab2)
var view3:UIViewController = UIViewController()
var lab3:UILabel = UILabel(frame: CGRectMake(0, 10, 200, 21))
lab3.center = CGPointMake(160, 284)
lab3.textAlignment = NSTextAlignment.Center
lab3.text = "I'am a label3"
view3.view.addSubview(lab3)
innerViews.append(view1)
innerViews.append(view2)
innerViews.append(view3)
var segmentControl:UISegmentedControl = UISegmentedControl(items:["blah", "blah1", "blah2"]);
segmentControl.selectedSegmentIndex = currentIndex;
segmentControl.addTarget(self, action:"segmentSwitch:" , forControlEvents:UIControlEvents.ValueChanged )
segmentControl.setTranslatesAutoresizingMaskIntoConstraints(false)
self.centerView.view.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(segmentControl)
Solution
func segmentSwitch(control:UISegmentedControl) {
selectView(control.selectedSegmentIndex)
}Is it strictly necessary for this to be a separate method? Can we not just do this:
func selectView(control:UISegmentedControl) {
let index = control.selectedSegmentIndex
// do stuff
}The only reason I can think not to do this would be if you've got other methods calling
selectView or if you intend to more than just selectView within the segmentSwitch method, but as far as I can tell, neither of these are the case.You have this:
nextView.viewWillAppear(false)
self.centerView.view.addSubview(nextView.view)
nextView.viewDidAppear(false)Followed later by this in a completion block:
currentView.viewWillDisappear(false)
currentView.view.removeFromSuperview()
currentView.viewDidDisappear(false)My first problem is that despite animating this change, we're sending
false as the animate argument to all of the willAppear-esque methods of these view controllers.My other problem is the order in which these methods are called.
The
viewWillAppear and viewWillDisappear methods for both view controllers should be called just before the animation block. Meanwhile, the viewDidAppear and viewDidDisappear methods should be called in the completion block of the animations.It's been a while since I've truly looked at the exact synching of these events between two view controllers, but I highly suggest you put an
NSLog statement in all of the view life cycle events and use a regular storyboard segue transition between the two to see the order and timing of which these are called. And better yet, do it in a navigation controller and use the swipe-left-to-right gesture to navigate backward. Notice as you start that gesture, the current view controller has viewWillDisappear: called, but it waits until the transition is complete for viewDidDisappear:. And ultimately, this means that if you start your gesture then go back, viewWillDisappear: can be called without viewDidDisappear:.You have a lot of code in
viewDidLoad. I'd highly recommend jobbing this out to other smaller functions, each of which get called by viewDidLoad.Finally, I'd highly recommend that you create a custom subclass of
UIViewController (or maybe UITabBarController). Ultimately, this seems like a very custom looking UITabBarController, right? Rather than writing all this code each time you wanted to implement it, it seems it'd be better if you narrowed it down to the navigation code and made it work for any (reasonable) number of contained view controllers, just as UITabBarController does.Code Snippets
func segmentSwitch(control:UISegmentedControl) {
selectView(control.selectedSegmentIndex)
}func selectView(control:UISegmentedControl) {
let index = control.selectedSegmentIndex
// do stuff
}nextView.viewWillAppear(false)
self.centerView.view.addSubview(nextView.view)
nextView.viewDidAppear(false)currentView.viewWillDisappear(false)
currentView.view.removeFromSuperview()
currentView.viewDidDisappear(false)Context
StackExchange Code Review Q#60983, answer score: 2
Revisions (0)
No revisions yet.