I have a tableView with two UITextViews. The user can add as many cells as they want by tapping on a "+" button. The tableView starts out with one row (cell). Lets say the user adds some information to the two textViews and then taps the plus button and scrolls to get to it. I call this function to dismiss the keyboard when a user scrolls so it isn't in the way:
override func scrollViewDidScroll(scrollView: UIScrollView) {
self.view.endEditing(true)
}
Now, the keyboard disappears and the user goes to tap on the second row's text field. The tableView jumps up (I think to accommodate the keyboard), but the textField can't be edited (no cursor and keyboard doesn't appear). If I go back up to the first row (row 0), the keyboard appears and I can edit the textView. Why is this happening?
There is a property on scrollView subclasses (e.g TableViews)
tableView.keyboardDismissMode = .OnDrag
Once the user begins a descending drag it dismisses the keyboard
scrollViewDidScroll calls everytime the tableview moves, so when "The tableView jumps up (I think to accommodate the keyboard)" it also calls and close the keyboard. You should add there some confines or put endEditing code in the other place.
Related
I have two tabs. The first tab contains a UITableViewController, with its tableView's cells containing some words. The second tab is for settings, containing a tableView, with a cell for setting font size. After the user taps the cell, the user will enter the interface for changing the font size. When the user presses the "save" button, (a button in the editing-font-size interface to save the adjusted font size.) the top view controller is popped back to the original tableView for settings.
I use observers to post notification when the save button is pressed, and the respective observers will update its view. I added an observer in the tableView for settings, and it works. When the top view controller for editing font size is popped, the original tableView is presented with adjusted font size.
However, when I added an observer in the UITableViewController in the first tab, the tableView is not reloaded. I have added a print message in the selector method of NotificationCenter.default.addObserver(_:selector:name:object:) and confirm that the selector method is called. The selector method looks like this:
#objc func reloadTableView() {
print("The method is called.")
tableView.reloadData()
}
The code that I use the font size in the first tab's tableView cell:
labelOne.font = UIFont(descriptor: fontDescriptor, size: fontSizeForLabelOne)
labelTwo.font = UIFont(descriptor: fontDescriptor, size: fontSizeForLabelTwo)
It seems very confusing to me, since the method to reload tableView is called, yet the table view is not reloaded? And since the font size is changed, when I scroll the tableView the new cells are randomly in the old font size or adjusted font size.
I have also tried it with labels, and it works on them even if it is in a different tab. In other words, I think the problem only occurs for tableView.
On the other hand, since it works for the table view in setting tab, am I right to say that tableView can only be reloaded when tableView.reloadData() is called when the tableView is about to be presented? If tableView is not presented and tableView.reloadData() is called, nothing will happen, and everything remains the same?
In short, is there anyway to ensure that tableView is reloaded when I change my font size?
Eventually I found a solution by, since my view controllers are managed by navigation controller, I pop the view controller and load it again as the alternative to reload the table view. Namely,
#objc func reloadTableView() {
navigationController.popViewController(animated: false)
navigationController.pushViewController(theViewController, animated: false)
}
The only downside of this is that the view controller will be reset to its initial state, i.e. if the table view in the view controller is scrolled down, when the user goes back to the view controller from setting, the table view is reset to its top position and does not show where it was scrolled to.
#objc func reloadTableView() {
print("The method is called.")
DispatchQueue.main.async {
tableView.reloadData()
}
}
in facebook messenger’s chatroom screen, We can scroll up the tableview to slide up keyboard and scroll down the tableview to slide down keyboard. in this situation, the keyboard is following my finger’s scroll action.
I can call the keyboard to show or hide, but i just can listen willShow, didshow, etc.. I can not access keyboard action or animation.
How can I do it?
UIScrollView has a property called keyboardDismissMode that allows you to set different behaviors.
scrollview.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Simply you can use-
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
I have a view hierarchy like this:
UIView -> UIScrollView -> UIView (contentView) -> UIButton
I have added code to the UIScrollView to activate zoom when the user double tap.
This is working well, the content view and the UIButton are zooming.
In my content view, I have some UIButton, my problem is when I double click on this button, I want the scroll view to zoom (this is ok) but I don't want my button to fire the event (this is not ok)
I want the button to only fire an event if the user click on it one time, but not with double tap.
In my case, the UIButton can be small, and I want the user to get the possibility to double tap on it to zoom, but to fire an action only if it is a one click.
I try to do this with swift
thanks a lot for your help
Instead of UIButton, use UIView or UIImageView as button and add UITapGestureRecognizer to it.
And implement the following logic:
if the view is double tapped {
call your zoom function
}
if the view receives single tap {
then perform your button click function
}
Hope it helps :)
I am using a custom class which is subclassing UITableViewCell. Now, when tableview goes in edit mode, I adjust the UIComponents on the cell inside layoutSubviews of my custom class. Now, when user tap on the "-" button the layoutSubviews get called once again and the UIComponents on the cell again repositions themselves which causes a weird UI flicker. I tried with below code in layoutSubviews but then UIComponents on the cell does not reposition themselves when user tap on edit and table comes in edit mode. Is there any graceful way to handle this.
if (self.editingStyle == UITableViewCellEditingStyleDelete) {
return;
}
Ok. Found this property which is set when user tap on the - button to show the delete button:
self.showingDeleteConfirmation
I have a TableView in my ViewController.
In the selected state, its cell's subview increases in width and comes outside it's bounds.
When I tap on this subview, touches are going to the View Controller's implementation of touchesBegan which is being used deselect the cell.
Now this subview is not being clipped and being allowed to go out, so Ideally the touches falling on it, should go to it but why are they going to the ViewController having the tableview ?
TableView is on left of the iPad screen (the View Controller) as a
sidebar.
Selected cell comes out like a drawer as shown below.
on tapping anywhere else in the screen, the drawer(selected cell)
goes back in.
The problem is the region in the selected cell, which goes outside the tableview's bounds,
If clicked, gives the touches to touchesBegan method in the ViewController.
Thus it ends up going back in.
=================================================
====== =
====== =
====== =
============= =
============= =
====== =
====== =
====== =
====== =
====== =
====== =
====== =
====== =
==================================================
Yes, this will happen because the updated cell is now exceed the tableview's width, so now obviously touches will go to the supperview of tableview. If you want to disallow that touch then you need to increase the width of your tableview as well, so cell view will comes under table and then you will receive the touches on tableview.
Actually there is one property of UIView called "clipsToBounds" and by default its value is "No" so this will not clipped the area which is outside the UIView and that's why you seeing the cell view but didn't get the touches and this will apply for all type of views.
Hope this will help you :)
I think instead of taking view controller try to create custom views one for table view and the other is your view which will be displayed like a drawer. create custom delegate for the tableview. applied functionality with animation like push and pop view controllers.I think this could be help you very well. set tableviewcell selection style property to none.