I currently have my app setup to receive push notifications. When I am in the app and I receive a push notification, I have a custom UIView slide down from the top of the screen and displays the notification (similar to the new version of Whatsapps). Essentially I am trying to mimic the banner style notifications in iOS 5.
What I am looking to do now is have that UIView clickable. When clicked, based off of the type of notification received, will bring me to a different view controller (similar to how whatsapp does it).
For example, I am in chatroom A. I receive a message in chatroom B. The slider view comes down, I tap that and it brings me to chatroom B. In the push notification I am essentially passing the chatroomID which I can use to identify which room (essentially some view) I would like to join.
I have a root view controller setup already with a navigation controller as well. I am modally pushing other view controllers as the user navigates throughout the app. Would I dismiss the current view and push the next view when receiving a notification?
Also how would I go about making my slider view detect taps like the iOS banner notification? (and maybe have a selected animation, similar to the "grey clicked style" in a UITableView)?
Here's a trick for detecting a tap on a view: Use a UIControl instead of a UIView (UIControl is a superclass of UIView). Then use the UIControl's addTarget:action:forControlEvents: method with controlEvents of UIControlEventTouchUpInside to send the object of your choice a message when the view is tapped. If you're configuring the view in Xcode's graphical editor, you can use the Identity inspector's Class field to change the class of your view from UIView to UIControl, and then you can configure the Touch Up Inside event.
(I learned this technique from iOS Programming: The Big Nerd Ranch Guide by Conway and Hillegass.)
You could very easily present a clear button over the view with an "if" statement that matches your criteria and perform a view animation from there with the transition back to the other view.
Related
I want to use 3D touch to navigate to a menu like in the contacts app or apple music. I have created a custom view controller for this however I don't want to use
-(UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location;
because the buttons won't be available to click until I pop into the ViewController.
I guess the alternative is to use
-(void)previewInteraction:(UIPreviewInteraction *)previewInteraction didUpdatePreviewTransition:(CGFloat)transitionProgress ended:(BOOL)ended
and navigate to the ViewController when I get the ended parameter is true.
However I am unsure how to create the blurring and scaling effects manually.
I have noted recently that each of my app view has one particular bug/behaviour: if user taps too fast on a UI component when the view appears, the tap is simply ignored. If the user wait a bit before tapping, the tap works.
Storyboard is used for the storyboard, tap gesture recognisers are on UIImageview and using IOS 10.2.
Through different forums i have read about the following options:
nest the call of "present view controllers" in main thread
Call CFRunLoopWakeup before presentviewcontroller
Add programatically the TapGesturerecognizer
change the states of "delays touches end" and "delays touches began"
disable 3d touch option as similar symptoms was reported to happen in other apps
All above have been unsuccessful.
Anyone would have met similar issues with the first tap just after the view load?
[Update: I realise this misbehaviour is not specific to this app. Two tests to try:
create an xCode Project for iPhone and two view controllers Controller A and Controller B. Two buttons : a button on Controller A view to go to Controller B view and a button Back in Controller B view to go back to Controller A view. Tap to go from View A to B, tap back in B and try immediately to tap on button to go to B. First tap doesn't work either.
Go in Settings of the iPhone. Tap On Notifications. Press On Settings to go back to Main Settings screen, Tap immediately back on Notifications. If fast enough, first tap doesn't work. Second tap works or waiting a bit before first tap.
Question is now: this looks like a common problem across iPhone apps. Would you know if there would be a common setting somewhere? or is this a common bug for given IOS version ?
]
Stephane
This is a general problem (the moment when the view controller is changed, the first tap will be ignored), but this is not a bug that will happen only because the switch view controller's animation has not yet been completed. If you set the animation to false , then the view controller can immediately respond to your click, no matter how fast (anyway faster than your hand) :)
iOS 7 introduces edge swiping to navigate backwards in a navigation controller (so long as you don't override the leftBarButtonItem, among other things).
Imagine I'm implementing an app similar to Apple Notes. In Apple's app, once the user taps into a note, there is a Back button on the top left, and a Done button on the top right. This view controller is automatically saved after the user navigates away. Even if the user swipes backwards while still editing the note, it will auto-save.
One way to implement this is to write to disk on each key stroke. However, I'm looking for a more efficient implementation.
Which method should I override to perform my auto-save?
To be clear, the auto-save code should be invoked in these three cases:
The user taps the Back button
The user swipes backwards
The user taps the Done button
So far, I've been implementing the save logic in viewWillDisappear, this minimizes the amounts of writes, and also takes care to save if the user kills the app.
Additionally, instead of implementing save logic in the Done button, the Done button can simply call:
[self.navigationController popViewControllerAnimated:YES];
... (e.g. via a delegate, or unwind segue) and it will automatically save as well. All three code paths will go through viewWillDisappear.
Although it could technically be implemented in viewDidDisappear, if the previous view controller needs to display the updated data, this method will be too late.
For more complex view controllers (e.g. those that have destructive behavior once the view controller is dismissed), there are several other things to consider:
Should the save be called if a modal is presented above the current view controller? (e.g. In Apple Notes, imagine that the share button launched a modal; should it save when you tap on this button?). If it is important not to save at this time, you can read the value of presentedViewController. If it has a value, that means viewWillDisappear is being called because a modal is being presented above it.
Should the save be called if a view controller is pushed on to the current navigation stack? (e.g. Again, in Apple Notes, if the share button used a push instead of a modal, should it save?) You can check the value of isMovingFromParentViewController in this case.
If the user taps the home button to quit your app, should it save?
If the user begins swiping backwards then cancels the swipe to stay on the current screen, should it save?
Imagine the view controller is in a modal, when the modal is dismissed should the destructive action happen? Check isBeingDismissed in this case.
Same as above, but imagine the view controller is the second page in a navigation controller than is being presented.
I have 2 UI views both with controllers attached to a tab controller.
ViewA - Used for authentication (contains login textfields and submit button)
ViewB - Used to display profile.
I have set ViewB to be disabled using the utility manager in storyboard, this is to prevent users clicking on the tab before logging in. Once authenticated in ViewA i want to notify ViewB to enable itself and display the profile.
From googling it appears that using NSNotificationcenter is the best way to do this, I have created a simple postNotifiaction that works fine - but I am unsure where to add the receiver in ViewB, I can not add it in ViewDidLoad because it does not load, and is disabled to start with?
Is notification center the best way to do this?
Also, how do i sent a notification to a view that is disabled?
Thanks
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html
Apple documentation link above pretty clearly states that NSNotificationCenter does not retain it's observers, thats why you can't release the dataAnalyzer there - it would be dealloc'd and the notification would attempt to post to a nil reference.
Subscribe to the notification(s) in the -init method of each view controller. That ensures the controller has been created and initialized, and makes each controller responsible for it's own actions.
I'm not entirely sure what your question is, could you rephrase it if the above didn't resolve your problem.
Also, be aware NSNotificationCenter will post to all observers, but it is not async - it waits for each one to finish processing the notification before sending to the next object.
Surely, you have a controller (AppDelegate if anything) that controls the disabled state of ViewB? You could listen for the notification from this controller instance and enable ViewB from it once it receives the notification.
If you must subscribe to the notification from ViewB, then register for it in its (ViewB's) init method (don't forget to unsubscribe from the notification in the dealloc method). This should work because even though the button used to get to ViewB is disabled, the ViewB instance would be instantiated with the launch of your app (or so I assume...).
If you don't instantiate ViewB until the button is tapped, then you must have the controller that enables/disables the ViewB button be in charge of listening for the notification and enabling the button to access ViewB.
I think this logic is a little ambiguous. This is what I've understood about your application:
-> Tab Bar Controller
---> Controller 1 - Login
---> Controller 2 - Profile (disable as default)
You have not to insert you notify into Controller 2 but in TabBar because it "controls" the other controllers (sorry for the word joke). I think the best solution can bes this:
TabBar
Observer of a notification about "user changed" and check it: if user is logged then enable profile controller, if user is anonymous then disable it.
Controller 1 - Login
When the user is logged in / logged out fire a notification of "user changed".
That's all, your controller 2 can live without know user state. Let me know if you have problem coding this logic.
Why you not just call [viewB enableItselfSomehow]; in -someAuthenticationSucceedFeedback method?
Registering notifications for just enabling/disabling view is a bad tone as for me
Did you disable the view or the tab button?
If you disable the tab button, you could enable it and switch to the profile tab by doing
self.tabBarController.selectedViewController = profileViewController;
You can place this code in ViewA's view controller. To get the profileViewController, you can use this code instead
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1]
Assuming that your profile is at index 1
I'm trying to add some finer control to the Storyboard controller and I hit a blockage with the back button.
I have a basic Storyboard with push transition. I want to be able to catch when the user presses on the back button (the one generated automatically) and decid if I want the view to go back or not.
The scenario is to show a message to the user asking if he wants to go back warning him that he is going to lose his work if he does,
Sounds simple, yet I can't find how to do it.
Any ideas
You don't get any sort of message by default when the back button is pressed. If you want to provide this sort of functionality, you have two options:
1) Provide a custom back button and set it as the leftNavigationItem of your UIViewController's navigation bar
2) Subclass UINavigationController and override a method such as popToRootViewController:animated:
Try using UIAlertView Delegate.
In your buttonPressed Action, provide an alert view with message with two buttons YES and NO.
define button at index action for YES and NO -ie- YES: dismiss current view and NO: remain on current view.
Search Apple Docs on alert view delegate