Please Clear Some Confusions Regarding Uiviewcontroller

transitionFromView:toView:duration:options:completion: confusion

You are more likely asking for an explanation of Apple's documentation than a specific question, if I understand your posting correctly.

Nevertheless I'll give you this explanation and I hope, it will help you:

You write:

Everything is working fine..

and that is, because you a doing well here!

According to the MVC design pattern (Model-View-Controller), you are using the classes UIViewController (the "C") and UIView (the "V") in your code.

A view contains the visual representation of objects (like labels, buttons, subviews, ...) without an logic for their behavior.

A viewcontroller provides the logic, e. g. IBAction methods and any other methods that you may implement.

Each UIViewController has its own "view" property containing the view, whose behavior the controller does manage. This view normally contains additional views, e. g. labels, images and buttons. They are subviews and are stored in the view's "subviews" array property. Btw, each view has such a subviews property - that is, how we can implement complex view hierarchies.

In your situation (multiple subviews that are managed by one common viewcontroller), the method

transitionFromView:toView:duration:options:completion:

hides "fromView" and unhides "toView" with the support of animations. It is a transition between to views. The paragraph from the documentation shall prepare you as a developer, that this method only manages the change of the visual representation and does not provide additional "services" for your view controller for the further management for the participating views.

That means, that you have to manage e. g. the state of the views (which view actually provides interaction for the user) by your own code. It seems to me, that you have managed this well!

In a wider scope, iOS supports UIViewController container as well - they can contain child view controllers (which again contain their view with its subviews). In such an architecture, there is another transition method from the SDK,

transitionFromViewController:toViewController:duration:options:animations:completion:

which allows you to implement transitions not between two views, but between two view controllers.

I hope this is not too much text and helps to make things clearer for you.

some confusions about property in Objective-C

Is it ok like the second one?

The two syntaxes are correct, generally speaking.

And what is the difference ?

The second one will also declare the ivar for you, but will only work correctly newer Objective C runtime systems.

And which is recommended ?

good question... I think they are pretty equivalent, provided you can restrict yourself to the newer ObjC runtime systems. For more hints at possible downsides of not declaring ivars explicitly, please have a look at this S.O. post.

Need assistance regarding UIViewController

If you are concerned about how UIViewController is release or destroyed then here is a scenario for you:-

Here is a button tap method in FirstViewController that presents SecondViewController (using pushViewController,presentModalViewController etc)

In FirstViewController.m file

- (IBAction)btnTapped {

SecondViewController * secondView = [[SecondViewController alloc]initWithNibName:@"SecondViewController" bundle:nil];
NSLog(@"Before Present Retain Count:%d",[secondView retainCount]);
[self presentModalViewController:secondView animated:YES];
NSLog(@"After Present Retain Count:%d",[secondView retainCount]);
[secondView release]; //not releasing here is memory leak(Use build and analyze)
}

Now In SecondViewController.m file

- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"View Load Retain Count %d",[self retainCount]);
}

- (void)dealloc {
[super dealloc];
NSLog(@"View Dealloc Retain Count %d",[self retainCount]);
}

After Running the code:

Before Push Retain Count:1

View Load Retain Count 3

After Push Retain Count:4

View Dealloc Retain Count 1

If you are allocating and initializing a ViewController, You are the owner of its lifecycle and you have to release it after push or modalPresent.
In the above output at the time of alloc init retain count of SecondViewController is One,,,,surprisingly but logically its retain count remains One even after it has been deallocated (see dealloc method), So require a release in FirstViewController to completely destroy it.

Using Custom View Controllers to manage different portions of the same view hierarchy

Well, I'd say "as long as it works", you can keep on doing like you do !
But to keep things "cleaner", I'd use my own objects.
Since ViewControllers are designed with other general features in mind (like working with navigation controllers and tab bar controllers), which makes it a bit "heavy" for a simple usage, like you do.
Plus, like you mentioned, some events are only called when the viewController's view is added to the main window.

Can't you use your own objects with Interface Builder ? If you create one (or several) UIView IBOutlet(s), it should work the same.

Need assistance regarding UIViewController life cycle

  1. Yes, if this instance of chatViewController is for this specific friend.

  2. The back button does a implicit popViewControllerAnimated: which pops
    the chatViewController from the navigation stack and destroys it (unless you have
    saved a strong reference to that view controller somewhere).

So there will be only one instance of chatViewController at a time (created in
didSelectRowAtIndex and destroyed by popViewControllerAnimated: when the
user goes back to the table view).

Confusion Regarding How to Use Capture Lists to Avoid a Reference Cycle

Well, it turns out my view controller was being retained by a block, but not the one I was thinking:

class MyViewController
{
deinit(){
print("Deinit...")
}

// ...

@IBAction func cancel(sender:UIButton)
{
completionHandler(self)
// View controller is dismissed, AND
// deinit() gets called.
}

@IBAction func punchIt(sender: UIButton)
{
MyWebService.sharedInstance.sendRequest(
completion:{ error:NSError? in

self.completionHandler(self)
// View controller is dismissed, BUT
// deinit() does NOT get called.
}
)
}

...so it is the closure passed to MyWebService.sharedInstance.sendRequest() that was keeoing my view controller alive. I fixed it by adding a capture list like this:

MyWebService.sharedInstance.sendRequest(    
completion:{ [unowned self] error:NSError? in

However, I still don't quite understand why the short-lived completion handler, passed to the web service class, executed once, and disposed, was keeping my view controller alive. That closure, not stored anywhere as a property, should be deallocated as soon as it is exited, right?

I must be missing something. I guess I'm still not fully thinking in portals closures.

touchBegan and TouchEnded overrides are affecting another UIViewController

Assuming the code shown is everything relevant, this makes sense. What's happening is this: the touch events are hit-tested to the joystickView, but because you haven't implemented a custom touchesBegan(_:with:) on that view, the touch event is passed up to the next UIResponder in the responder chain. That would be the LandScapeViewController. But that class also doesn't implement a custom touchesBegan(_:with:), so the event passes to the next class, which in this case is PortraitViewController. Because PortraitViewController does implement that method, it gets called. There's your confusion.

To fix this, implement the touches… methods on UIResponder for either joystickView or LandScapeViewController, even if they do nothing – but don't call super in them! Note the following, from the touchesBegan(_:with:) documentation:

If you override this method without calling super (a common use pattern), you must also override the other methods for handling touch events, even if your implementations do nothing.

Where you're overriding touchesBegan(_:with:), you probably don't want to call super. This is because the super implementation is the one that says "oh, shoot, I don't know how to handle this – pass it up the chain!" But when you handle the touch, it should end there, because you're handling it! So only call super when you're not handling the touch – which in your case looks like never, at least for PortraitViewController.

For more information, check out Event Delivery: The Responder Chain.

Is UIViewController's beginAppearanceTransition:animated: method available in iOS5

I filed a bug report with Apple about this discrepancy and got the response that the methods are available in iOS 5.0. The headers are right and the documentation is wrong. I've filed another report to ask for the documentation to be updated...

The methods were added to the public headers in the iOS 6 SDK, but are available and can be used on devices running iOS 5.0.

Update (28-Aug-2013)

The documentation has been updated to show that beginAppearanceTransition:animated: and endAppearanceTransition are available on iOS 5.0.

View Controllers - Suggestions from documentation

I agree with you that could get some clarification, you should give them a feedback about that.

Now for my interpretation.

1. Yes NSObject subclass

2. I think they mean different subareas of your screen. Which would means don't create multiple UIViewController subclass to control deferent part of your screen, create custom controller managed by a single UIViewController.



Related Topics



Leave a reply



Submit