would you tell me,, what steps i have to add in applications to move values from a view to another when press a button
You can use The NSNotificationCenter which implements the Observer pattern. You have one view that listens for an event and the other view notifies any listeners when the event is triggered, in your case the button pressed.
This SO response has good information on it.
What is NSNotification?
In addition to notifications and delegates, you can always do the quick and dirty method of passing a self class reference forward from one view to the next, and use the previous view class reference in your current view. Please see my blog post about this:
http://www.dosomethinghere.com/2009/10/04/passing-values-and-messages-between-views-on-iphone/
Related
I have created all my views programatically and to the UIView I have created an extension. This extension is present in a different file called App+Extensions.swift
extension UIView {
func setupParentView() -> UIView {
//...
}
}
The setupParentView() gives me a view with my navbar and background colour. As the design is same everywhere I have used this function. This function is called everywhere in viewDidLoad. So, now in this function the navabar consists of points which need to updated every time the user has purchased/spent it.
So, now as this method is only called in viewDidLoad the function is not called again and the point value do not change in the navigation bar. So, how can I update the point value every time it is changed? I thought of using Combine, but this app will be available for iOS 12 users as well, and I am not using RxSwift, so any help?
Well ViewDidLoad won't get refreshed because your view is now in the stack hierarchy. Some override methods that do get called which have a relation to the view are viewWillAppear, viewDidDissapear, and viewDidAppear.
If your view is going back in forth and the point button needs to be updated everytime your view re-appears consider putting the "refresh" point number in one of the above methods.
Note if your sending info back and forth between two views its also best maybe implement a delegation pattern or an observer.
Use notifications.
In other words, have points be a property of a global object that lives off in "data space" as a singleton. Now just use a property observer so that whenever anyone changes that object's points property, it emits a notification through the NotificationCenter.
That way, any view or view controller that needs to update whenever the points property changes just has to register for that notification when it comes into existence.
[Basically, this is the mechanism, or one of the mechanisms, that you would be replacing or even using directly if you were using Combine or RxSwift.]
Create a custom view called NavBarView
This NavBarView has a property called point
var point = 0 { didSet { updateView() } }
You want to avoid singleton, single view object, so that not everything is coupled together.
You don't need RxSwift or notification to do this.
Let's assume I have an address book App.
So from the address list I now push to a detail view like so:
User taps on cell in the master list
Segue showDetail is invoked
In prepareForSegue: I set the model object contact of my ContactDetailViewController
viewWillAppear I add an observer for self.contact
So now when the contact object changes in the background, the detail view will automatically be updated.
In viewWillDisappear I remove this observer (I guess it's clean because it is symetrical).
However, viewWillAppear: is called after I set the contact. So should I setup the KVO differently or simply call my updateView function in viewWillAppear which is a bit stupid because I want to get rid of those calls with KVO in the first place.
When you call addObserver:... you want to include the option NSKeyValueObservingOptionInitial. This will cause KVO to send the equivalent of a didChangeValueForKey: notification (i.e. an "Initial" notification) in the same call that adds the observation. This should cause your view to update at that time.
Any help would be appreciated.
I am looking for a way to programatically notified that a view is loaded from outside of that viewController.
Lets say my main view has 5 buttons, after the view is loaded and the buttons appeared I want to be notified in another file (outside of that viewContrller) that it is loaded. How/Where can I check this and be notified?
Do I need to do some Aspect Oriented Programming?
Use NSNotificationCenter. You can communicate between classes.
NSNotificationCenter or a delegate method is the most appropriate way to accomplish this.
Listen for a custom NSNotification inside your other object. Have your view controller post that notification during whichever part of its life cycle makes most sense (viewDidLoad, viewDidAppear ...).
If you can't post a notification, then observing a keyPath might be the way to go. For example, you can put something like this in your control object and then implement observeValueForKeyPath::
[viewController addObserver:self
forKeyPath:#"view"
options:NSKeyValueObservingOptionNew
context:NULL];
While you can do this with notifications as others have suggested or KVO, this strongly suggests a design problem. You should never be accessing a view controller's internal views directly. So the deeper question is: why do you want to know?
The most likely cause in my experience is that you're letting some other object set the titles or modify enabled. This breaks MVC and leads to the kind of problems you're probably trying to fix. The correct way to handle this is to put the data into a model object that is shared between the various view controllers. The current view controller can then observe changes on the model and update its UI elements appropriately.
I have a view with multiple text fields and I want to do the same effect that the Contacts application does when you click on a text field would otherwise be hidden by the keyboard when it comes up. When I dismiss the keyboard I plan on moving the view back down properly.
I suspect that I do this by changing the Frame value, but I need this to be animated so that it isn't jarring to the user.
Advice? Examples?
Wrapping your view in a UIScrollView is indeed the way to go. As well as on the textFieldDidEndEditing delegate, you could instead subscribe to the UIKeyboardDidHideNotification and UIKeyboardDidShowNotification and when you receive a notification that the keyboard did hide/show then scroll your view appropriately. I can post code examples for the keyboard notifications if you need it : )
Edit
Figured I'd post the code anyway - someone might find it helpful:
You need to declare listeners for the notifications:
NSObject hideObj = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidHideNotification, HandleKeyboardDidHide);
NSObject showObj = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidShowNotification, HandleKeyboardDidShow);
then your Action methods would look something like:
void HandleKeyboardDidShow(NSNotification notification)
{
scrollView.ScrollRectToVisible(textfield.Frame, true);
}
void HandleKeyboardDidHide(NSNotification notification)
{
// scroll back to normal
}
Edit 2
So if you'd like to remove the Observers when the view is destroyed, first you need to ensure you assign NSObjects when adding the observers then use the following code to remove them:
NSNotificationCenter.DefaultCenter.RemoveObserver(showObj);
NSNotificationCenter.DefaultCenter.RemoveObserver(hideObj);
Hope that helps.
I just did this on an application. I used a scrollview to wrap my entire view, and then used scrollToRectVisible on the textFieldDidEndEditing-delegate method. It worked perfectly!
The Apple documentation on about the keyboard management topic is pretty good and contains code (at the bottom) for most situations that that you can copy/paste right into your app.
Best of luck.
I have a view controller which gets an NSObject conforming to a protocol and then displays a view with the object's properties.
The question : How can my controller know that a property of this object has been modified and then refresh the view ?
Thanks a lot
Thierry
There are three ways of doing this:
Have the object call a method in the controller in response to an event e.g. a user clicking the button. This is usually done using an IBAction.
Set the controller to be the delegate of object e.g. a UIWebView sends a message to its delegate when it finishes loading a page.
Use a notification. The object generates the notification and then one or more objects (including the controller) registers to listen for the notification. This is usually not used with interface elements although it can be.
I can't tell you more without more detail about the specifics of your project.
Your viewcontroller should conform to your .
In your model, all your set methods should trigger appropriate functions you define in your modelchangedprotocol.
This OO design pattern is also known as "Observer" design pattern.