Unexpected UIPageViewController behaviour - ios

I'm currently building a app using UIPageViewController. It is working as I expected until it reaches last page which contains numbers of UITextField.
But when I tapped one of instances of UITextField, it suddenly jumps to the previous page without any reason instead of showing a keyboard. When I scroll through to the last page and tap a text field again, it works well without any problem.
It is also fine when it shows last page immediately by tapping the navigation button that links to the last page and that is attached to the UIPageViewController instance.
This problem happens only when I scroll through pages from first to the last, and it happens only once at the first try.
I suspected low memory issues, so I set breakpoints in -didReceiveMemoryWarning method of both UIPageViewController instance and the last page view controller. But they were never called.
The second try is that I added a breakpoint in the last page view controller's -willMoveToParentViewController: method and set its condition to parent == nil(when it's removed from parent view controller, which is the UIPageViewController instance in question)
When I run the app, the breakpoint's call stack says that the method is called by UIPageViewController's -_flushViewController:animated:.
I don't know why this -flushViewController:animated: is called. If I can figure out the cause, it will help me with fixing the problem.
Is there anybody who can help me?

I'm not sure what it is in your code that does this, but one probable approach in debugging this is to try and catch the UITextField's UIKeyboardWillShowNotification event to check if it's firing properly.
Also try to set a breakpoint at your page's viewWillAppear event to inspect if all of the UITextFields have been instantiated properly -- I would suspect that at the point where you tapped the first text field not all of them have instantiated yet, meaning that the object receiving the tap action will be your UIPageViewController instead of the UITextField.

I found the answer here:
Cannot Impliment UITextview inside a UIPageViewController
Credit goes entirely to him.
I can confirm that it works. Here is what I did in my view controller:
//TextField
UIScrollView *textFieldScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, width, height)];
[textField setText:#""];
[textField setBackgroundColor:[UIColor whiteColor]];
[textField.layer setCornerRadius:5.0f];
[textField setDelegate:self];
[textFieldScrollView addSubview:textField];
[_someView addSubview:textFieldScroll];
Works like a charm. Let me know if you have any more questions.

Related

UITextView Will Not Scroll to Top

Update - I now believe this is due to me calling [view.details scrollRangeToVisible:NSMakeRange(0, 1)]; too early--meaning before the constrains have been applied and layouts recalculated.
I figured this much out by calling the scrollRangeToVisible after the view was shown and after I took some action on the cell. (This would guarantee that all layout changes were complete before I made that call.)
Thus, what I need to know now is Where should I make this call? such that it occurs after the layouts?
Original Post
I've tried many solutions, but none of them seem to work.
I have a UITextView as a subview to a UIView -- a container for the text view plus a few other items. When a user clicks on a cell in a tableView, I pop up the UIView container to show more details--the full text.
Configuring the view, I set the textView.text value to my long string, I update the font, I set the color, and I show the container view. Unfortunately, it shows the text at the bottom of the textview rather than at the top.
I've tried the following solutions, to no avail--each one results in the same behavior as above: it still shows the text at the bottom of the textview.
Attempt 1: scrollRangeToVisible
[self.textView scrollRangeToVisible:NSMakeRange(0,1)];
Attempt 2: contentOffset (tried each of the following, but none work)
[self.textView setContentOffset:
CGPointMake(0, -self.textView.contentInset.top) animated:YES];
[self.textView setContentOffset:CGPointMake(self.textView.contentOffset.x, 0)
animated:YES];
[self.textView setContentOffset:CGPointMake(0, self.textView.contentSize.height-textView.frame.size.height) animated:YES];
Am I fishing with those last items? Yes. I've run out of ideas. I've checked the values of contentOffset.y and contentInset.y -- both are zero.
I create the UITextView in a subclass of UIView called PrayerPopupView. Here's the process:
In my main UIViewController where the table exists, a user touches a cell. Based on this action...
I create an instance of PrayerPopupView in this view controller
In the creation of this view, the UITextView is created
The textView.text value is set.
I call `[self.details scrollRangeToVisible:NSMakeRange(0, 1)];
I use a custom class (KLCPopup) to add the view to the UIWindow but I also tested by adding my PrayerPopupView directly as a subview of the view controller rather than using KLCPopup, just in case it mattered. Both yield the same result of text not scrolled to the top correctly.
Since adding the scrollRangeToVisible didn't work in the custom view itself, I also added it in the UIViewController before showing the PrayerPopupView ([prayerPopupView.detailsTextView scrollRangeToVisible:NSMakeRange(0, 1)];), and still the same result.
Here's a screenshot of the view:
Here's a screenshot of the view properties in the debugger:
This shows the view hierarchy in the debugger:

Pull To Refresh Jump in iOS

When I slowly pull down to refresh, I see the UIActivityIndicator circle slowly get more complete before it starts the refresh. Just before the circle is complete and the refresh actually triggers, the content jumps/jerks down and then the circle starts spinning. I only notice this when I pull down slowly.
I'm using the pull to refresh inside a scroll view called mainSV
self.refresh = [[UIRefreshControl alloc] init];
[self.refresh addTarget:self action:#selector(handleRefresh) forControlEvents:UIControlEventValueChanged];
[self.mainSV addSubview:self.refresh];
Why does this jump/jerk happen?
It's probably a bug in iOS. Your setup is correct, and I see the same thing in my app.
I suspect the jump/jerk is due to a "double" action.
There was a change to refresh implementation following the release of Xcode 5.
As such, the requirement to set a target action as described in the Apple Documentation is no longer necessary.
As you are using a Storyboard, in your Interface Builder / Storyboard file, select your storyboard scene (table view controller).
In the attributes inspector, under the subheading Table View Controller, select the item "Refreshing" and change the setting from "Disabled" to "Enabled".
Delete or comment out the three lines of code you have included in your question. (When it was required, i.e. prior to Xcode 5, I placed this code in my viewDidLoad TVC lifecycle method.)
If not automatically inserted into your code, then add this as either a public or private IBAction...
- (IBAction)refresh:(UIRefreshControl *)sender;
and wire to your scene / table view controller to the Sent Event "Value Changed".
Ensure your refresh action is properly configured...
- (IBAction)refresh:(UIRefreshControl *)sender {
[self.refreshControl beginRefreshing];
// Refresh code for your TVC
[self.refreshControl endRefreshing];
}
Note that no property is required to be set for refreshControl - I suspect there is a trigger to automatically synthesise this when you choose the setting Refreshing [Enabled] in your TVC attributes in the storyboard.
If you need to call the refresh from in your code, use this line...
[self refresh:self.refreshControl];
I would need to see the rest of your code (or at least the scrolling + refreshing methods) to diagnose the problem.
Here's our tutorial for implementing custom pull to refresh controls in objective-c and swift. If you follow this tutorial you shouldn't see any jumping or jerking.
http://www.jackrabbitmobile.com/design/ios-custom-pull-to-refresh-control/
Hope it helps!
Old questions but if someone still has this issue and you are using NavigationController just make your NavigationBar "Translucent".
Using non translucent NavigationBar causes the tableview to jump slightly when UIControlEventValueChanged is fired for some reason.
XCode 10.1

Single Tapping not being detected on dynamically created uibuttons

It was necessary to create a subclass of UIButton, lets call it subButton. These subButtons are instantiated one by one and dynamically added to an UIScrollView object.
Unfortunately the subButtons aren't reacting as expected. After scrolling away from the first dynamic generated subButtons and then returning back to them. They loose their reactivity to single tapping. I can not explain this behaviour. Can somebody explain why its behaving this way?
Many thanks.
Source code
self.subButton = [[SubButton alloc]initWithFrame:CGRectMake(69.5, y, 201, 114)];
[self.subButton setBackgroundColor:[UIColor blueColor]];
self.subButton.imageData = imageData;
self.subButton.videoPath = videoPath;
self.subButton.vidIndex = _indexVideo +1;
[self.subButton drawVidPreview];
[self.subButton setTag:(_indexVideo +1)];
[self.subButton addTarget:self action:#selector(handleSingleTap:) forControlEvents:UIControlEventTouchUpInside];
[self.videoScroll addSubview:self.subButton];
[_videoPreviews addObject:self.subButton];
The subButton method drawVidPreview adds some subviews to itself.
Do the buttons not respond at all, or just not to single-tap? That might help us help you.
If they don't respond at all, I would check your view hierarchy to make sure no other view (perhaps invisible) are sitting above your buttons. Or, perhaps are the buttons not being added to the parent view you think?
Please make sure you are not adding the same UIGestureRecognizer instance to all of the UIButtons, instead for each UIButton you need to add a separate instance, however all gesture instance can point to the same target.
At last, i could solve the problem. The reason why the first subButtons did not respond to single tapping with UIControlEventTouchDown is because the uiScrollview content offset was set to a negative y value. This first of all was not necessary and was done out of pure laziness. I corrected it by giving it a positive value.
So my conclusion is, if you do not set the content offset or content size of the scrollView correctly, some dynamically added buttons to the scrollView might not respond to tapping appropriately. This is even the case if all Buttons are placed completely on a uiScrollview object.
This I could confirm by playing around with the content size of the uiScrollview instance too. I changed size of the y value of uiScrollviews instance just by few points and then some of the last buttons did not respond to tapping anymore.
Just by increasing the content size of the y value again, made the buttons responsive again.

iOS 6 UIGestures (Swipe) stops working with QLPreviewController

In iOS 6 beta 4 and iOS 5.1.1 I have had left/right swipes allowing users to swipe between different QLPreviewControllers, hosted in a UIViewController.
In the released version of iOS 6 the swipes are now completely ignored.
Attempted to put a UIView as a subview of the preview controller in an attempt to get the view hosting the preview controller to intercept the swipes before the preview controller has a chance to swallow them, but these are never triggered.
Any one seen this or know of a work around.
Thanks,
I had the same problem but with UITapGestureRecognizer not working on QLPreviewController. In iOS 6 that thing is like a black hole for UIGestureRecognizer objects...nothing makes it out of there!
However I did find a workaround. I am subclassing QLPreviewController, so in my subclass I abused the (relatively) new viewWillLayoutSubviews method and added the following snippet:
UIView *overlay = [[UIView alloc] initWithFrame:self.view.frame];
overlay.backgroundColor = [UIColor whiteColor];
overlay.alpha = .002f;
for (UIView *v in self.view.subviews)
{
[v addSubview:overlay];
}
[overlay release];
It may be overkill, but I basically went into the all of the quick look subviews and added a view to them that WOULD accept the gesture. I went with .002 alpha because making it lower would cause the gestures to be ignored again.
I have also found that using the same code, UIGestureRecognizers have stopped working under iOS 6. But it is not that totally broken. Apple Development Sample project "SimpleGestureRecognizers" still functions. After comparing the code, I found that explicitly "addGestureRecognizer" resolved the problem (besides all the other steps you used to do under IB). Assuming your one of your IBOutlets names leftSwiftRecognizer, you could do:
- (void)viewDidLoad
{
[super viewDidLoad];
....
// swipe recognizer
[self.view addGestureRecognizer:self.leftSwiftRecognizer];
}
Your attempted solution was close, but probably backwards from what you should have done. Instead of adding another view as a subview of the preview controller, add the preview controller as a subview of the UIView.
Subview the preview controller inside a standard UIView. Then, reassign your gestures to the UIView's gestureRecognizers collection, removing them from the QLPreviewController's collection.
Not sure why this changed, but I had the same issue with my app, except for me it was the UITableView that wasn't scrolling anymore.

iOS keyboard won't dismiss after view dissappears

I have been looking for a similar questions but so far the answer doesn't fit my purposes. I have a UITableViewController inside A UINavigationController with custom UITableViewCells containing textfields inside. When I click on the textfields they become the firstResponders and when I click return they resign it. So far so good.
My problem is one of these cells is performs a Submit function. After this is done whenever I press the textfields the return button doesn't dismiss the keyboard anymore.
My question is, since I'm not releasing anything, why do these textfields stop listening to the resignfirstresponder message?
UPDATE: I finally got this working by setting an UITextfield ivar in the class, making it the first responder whenever the textfield begins editing in :
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField setTextColor:[UIColor blueColor]];
focusedTextField = textField;
}
And calling [focusedTextField endEditing:YES]; when i press the submit button. Just added this after seeing some answer in SO, but I can't remember the link, sorry.
Hope it helps.
If you have declared a method for return(let's say your textfiled is called textField) use this code in your method;
[textField setUserInteractionEnabled:NO];//but this may restric you if you need to use it again
But if you use standard return property of the keyboard it may be something related to Apple's restrictions

Resources