Inputs do not reset after clicking cancel button and reopening the view - objective-c

I have a form with some text fields, toggles and pickers. Everything works just fine except for When I input something on text fields and click cancel button and reopen the form, inputs are still there. Just can't figure out why.
Now, the app I'm working on is huge. Therefore, can't share everything but here's how my btnCancelClicked method looks like:
- (IBAction)btnCancelClicked:(id)sender {
if(onCompletion) {
onCompletion(self.myView, YES);
}
}
What's the logic behind implementing a cancel button? What is the step by step process to close the view and not saving whatever the user input is? I'd like to understand what the problem behind this might be. I appreciate any help.
Edit: [self.myView setNeedsDisplay]; or [self.myView setNeedsLayout]; are not helping.
Edit2: TextViews are also working properly, meaning that when I type something and then click cancel and reopen the view is at its initial state. The only problem is with TextFields. Should I do something different for them?

After dismissing the view, the view is still in memory. So you get all the entered value as it is. you have two way to achieve your desired outcome:
After dismissing the view, set it to nil. create a new view while you are presenting.
Before presenting your view, programmatically reset your controls.
you mentioned TextViews are working perfectly, is TextViews created manually?

Related

UITextField losing firstResponder after view appears

I have a UIPageViewController. One page has a single button, and the other page has a UITextField with a button. When the page scrolls to the view with the field, I'd like it to becomeFirstResponder and open the keyboard. Here's what happens:
I call [self.locationQuery becomeFirstResponder] ViewController's viewDidAppear method. But it never opens the keyboard.
I do the same in viewWillAppear, and it appears briefly, but then is quickly dismissed.
If I'm on the page with the text field, and pull the page partway and let it go (without changing pages), self.locationQuery receives focus just fine.
It seems like something else is grabbing firstResponder status from the field, but I haven't the faintest idea what, and why it would only be happening when the page changed (rather than revealed after a failed page turn). Any ideas?
Update
I created a way to crawl the views to see if any other views were, indeed, taking firstResponder (from an answer to this question: Get the current first responder without using a private API). Results:
When I explicitly give first responder to the text field, the method reports it has first responder status.
When I don't, it returns null.
Now I'm even more confused.
I don't really understand the nature of what was causing my issue, but I was able to fix it by wrapping the call in an async dispatch in viewDidAppear:
dispatch_async(dispatch_get_main_queue(), ^{
MapManualViewController *strongSelf = weakSelf;
[strongSelf.locationQuery becomeFirstResponder];
});
This one stole a few hours from my life. Here is the Swift 3.x implementation.
DispatchQueue.main.async(execute: {() -> Void in
let strongSelf: MapManualViewController = self
strongSelf. textField.becomeFirstResponder()
})
I also put it in viewDidAppear

How Can I Change UIImages in a ScrollView based on a User's Input

Okay gang, I'm scratching my head on how to accomplish this one so I wanted to put it out to the world at large.
Essentially what a client wants is a way to toggle PART of a view based on whether the user selects a "Yes" or "No" option. My question is how would I go about accomplishing that?
Allow me to provide some more details. Within this specific app resides a form (a form with custom text fields, picker views, switches, sliders and other UI elements) that have all been laid out in a Storyboard, then programmed to function. About 3/4 of the way down this form, the user will be greeted with a "Yes" or "No" option and a button for each. The trick is that each view needs to have its own UI elements (text fields, sliders and buttons) appear ONLY when one of the options is selected and only BELOW the "Yes" or "No" option (all the elements above it need to remain, stay in the same place and hold the information the user enters).
An example : If the user hits the "Yes" button, below it 3 lines of text followed by a UIButton and Text Field would appear. Underneath this, other navigation buttons which navigate to other ViewControllers would appear. However, if the user hits the "No" button , all of those items I mentioned a moment ago would need to disappear, and instead a different set of text fields, labels, buttons and background image would need to appear. The navigation buttons will also need to link to other ViewControllers, different from the buttons in the "Yes" option. At this point I suggested to the client that a Navigation controller rooted at the bottom of the screen would be a good idea, but they are vehemently opposed to this and instead want the navigation options to be "dynamic" (or change according to which option is pressed, "Yes" or "No").
I have thought to attempt this programatically by simply using each button to load in a different image, this works just fine. The hitch then becomes twofold;
1) When I attempt to load the other UI elements that I get no way to lay them out in a storyboard and thus they appear in sporadic locations and
2) All this needs to be contained within a scroll view, which ALSO needs to change its size depending on how much space is needed below the yes and no option. Naturally the "Yes" section is 3 times smaller than the "No" section.
So, any ideas on how to make all this happen? I should mention at this point that the client also does not wish to simply navigate to a different ViewController, they very much want all this to occur on the same screen. I wish I had some code to share but we are still in the "design" aspect of this project and as such, very little code has been written. Any advice will be much appreciated as I've never been greeted with this type of build request before.
Create a UINavigationController object and set your view(say yourViewController) where your Yes and No buttons exist as a root view controller as below
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:yourViewController];
Now when user press YES/NO button on yourViewController view than you can programmatically create all controls text field and buttons and set frame according to your view. like
UITextField *txtField = [[UITextField alloc] initWithFrame:CGRectMake(enter frame accordinglly)];
[self.view addSubview:txtField];
same you can add more controls like buttons or any other controls.
after that when user press any the button(on which you want another view to display) you can push other view in the navController as below
[navController pushViewController:otherViewController animated:YES];
you need to keep track of navController in your yourViewController
when you want to go back just pop view from navController
[navController popViewControllerAnimated:YES];
PS: please be watchful for memory deallocation as well.

Keyboard appears on top of view where no user interaction should be allowed

I have a window-based project with two UITextFields to take input from the user.
Both are in my view controller.
I have to parse stuff in the background, so I need something that blocks user interaction in the meanwhile.
I came across this Cocoa With Love tutorial to create a loading view on top of everything. It actually works pretty well, for the most part; it works when ever the text field resigns first responder.
There is one circumstance where it doesnt work, though. When I type something in the first text field and then select the second one, the loading screen will appear, but the keyboard is on top of it, so the user could type something. I want the loading screen to be on top of the keyboard.
In the tutorial, it says to call the keyboard's superview. What is the keyboard's superview?
I tried the following different snippets in my view controller, but nothing works.
loadingView = [LoadingView loadingViewInView:[self.view.window.subviews objectAtIndex:0]];
loadingView = [LoadingView loadingViewInView:self.view];
loadingView = [LoadingView loadingViewInView:self.view.superview];
How can I make the loading screen appear on top of everything ?
The simple solution is to dismiss the keyboard when you show the loading view. I don't think you're allowed to put anything on top of the keyboard.
That said, you could try using the root window as the view to see if that has any effect.

NSTextView wont update unless I click on it, and it wont focus. Any ideas?

I dont have time right this second to put some sample code, (Ill edit my question tomorrow and add some) but basically what happens is that I have a Window. It works fine usually, but if I use
[myWindow setStyleMask:NSBorderlessWindowMask]
to make it borderless, the NSTextView it contains will stop gaining focus even when you click on it: the ring will never appear, the cursor wont change and the scroll bar will remain gray.
Something else that happens when I make it borderless is that it wont update! I basically have this
[lyricsView setString:someString];
to update the string inside it. The Console marks me no errors, but the string wont appear in the Text View unless I click on it.
All of this stops happening if I remove the line setting the styleMask to Borderless. Any ideas? Suggestions? Comments? Cheers?
Thank You!
Kevin
From the documentation of NSWindow:
The NSWindow implementation returns YES if the window has a title bar or a resize bar, or NO otherwise.
So subclass your window and add this line
-(BOOL)canBecomeKeyWindow
{
return YES;
}

How To: hide keyboard when UITextView is out of view?

I've put some UITextViews in a UITableView(Controller) with custom cells, and I'm running into a problem. The user can hit the "Edit" button up in the navbar to set the table into editing mode - each custom cell has its own way of enabling its individual UITextViews for text entry. That works fine.
The problem I'm having is that if focus is on a text view that gets scrolled out of view when the user hits "Done", the keyboard remains and the textview remains in edit mode. This doesn't happen if the textview is in view. More specifically - the cell i'm looking at is at the top of the screen and will act funny if it's scrolled above the iPhone screen. I don't seem to have the same problem when the textview at the bottom of the table gets scrolled out.
I've done just about every single permutation I could think of to get the view to resign first responder, but it appears to me that the hidden textview doesn't get/send any messages (even any delegate methods) until it is back on to the screen OR some other text view gets focus.
What am I missing?
After working on this for the better part of a full day, this is what I learned:
You can't actually access
out-of-view cells in UITableView. I
guess that makes sense, though
frustrating in my situation
No amount of redrawing or trying to
manually resign first responder is
going to help, even when you point
to a specific cell in a specific
row.
setEditing: animated: (called when you hit the "Done" button) isn't the only thing going on
I'm going to guess that the reason the UITextView remains in edit mode is because the cached version of the cell is in edit mode and cached cells/data aren't called by these various table methods (like setEditing:animated:)
This is the solution I found: (at UISearchBar and resignFirstResponder):
* calling [self.tableView endEditing:YES] causes all views to resign first responder, which means my UITextView is no longer selected. I'm not sure why it works this way, but appears setEditing: is sent to each cell & redrawn accordingly.