问题
I'm currently battling with the keyboard covering some textField issue on my Swift based iPhone app.
This image shows the primary problem (top three images show the problem, bottom three are what it should be doing):
When the textField in the tableViewCell is edited I want to move the whole tableview and navigation bar up. I can do this with the code below (snippets taken from the viewController):
var tableViewShiftedUp = false
...
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! QuantityTableViewCell
let componentLocationQuantity = tableViewData[indexPath.row]
if let locationString = componentLocationQuantity.location.valueForKey("location_name") as? String {
cell.setCellContents(locationString, quantity: componentLocationQuantity.quantity.floatValue)
cell.quantityLabel.delegate = self
}
//get stock level related to current build rate and lead time (good - green, warning - orange, urgent - red)
let status = model.determineStockLevelStatus(component)
cell.setQuantityLabelBackgroundStatusColor(status)
if editingMode == true {
cell.makeQuantityEditable()
}
//add control event to detect text change
cell.quantityLabel.addTarget(self, action: #selector(quantityCellTextChanged(_:)), forControlEvents: UIControlEvents.EditingChanged)
cell.quantityLabel.addTarget(self, action: #selector(quantityCellSelected(_:)), forControlEvents: UIControlEvents.EditingDidBegin)
return cell
}
...
//MARK: - UITextfield delegate
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
if tableViewShiftedUp == true {
moveTable()
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func quantityCellSelected(textField: UITextField){
if tableViewShiftedUp == false {
moveTable()
}
//check table was moved
print(tableView.frame.origin.y)
}
func hideKeyboard(){
self.view.endEditing(true)
if tableViewShiftedUp == true {
moveTable()
}
}
func moveTable(){
if tableViewShiftedUp == true {
animateTableViewMoving(false, moveValue: 250)
animateNavigationBarMoving(false, moveValue: 250)
tableViewShiftedUp = false
} else {
animateTableViewMoving(true, moveValue: 250)
animateNavigationBarMoving(true, moveValue: 250)
tableViewShiftedUp = true
}
}
// moving the tableView
func animateTableViewMoving (up:Bool, moveValue :CGFloat){
let movementDuration:NSTimeInterval = 0.0
let movement:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration )
self.tableView.frame = CGRectOffset(self.tableView.frame, 0, movement)
UIView.commitAnimations()
}
// moving the navigationBar
func animateNavigationBarMoving (up:Bool, moveValue :CGFloat){
let movementDuration:NSTimeInterval = 0.0
let movement:CGFloat = ( up ? -moveValue : moveValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration )
self.midNavigationBar.frame = CGRectOffset(self.midNavigationBar.frame, 0, movement)
UIView.commitAnimations()
}
And it works fine when moving directly to the textField in the tableView. However, when I am already editing a textField outside the tableView the shift up doesn't happen and so the shifting toggle gets out of sync.
I've printed the tableView frame origin:
//check table was moved
print(tableView.frame.origin.y)
so I can see what the tableView is set to and on that first move from textField outside the tableView to textField inside the tableView, this property is what I would expect it to be 134, however it's still at 384 on the screen which it prints the next time it's called.
The problem doesn't occur when moving within cells in the tableView.
It feels like I've got some kind of race condition problem or I'm missing some delegate method being called that is throwing everything off when transitioning from one cell to the next.
Help would be great.
回答1:
Check out this library: https://github.com/michaeltyson/TPKeyboardAvoiding. Designed so that it gets the keyboard out of the way of text fields.
回答2:
When you use autolayout you cannot resize frame directly like you doing, you must work with constraints (you can create IBOutlets for constraints created in IB or add new ones, then send layoutIfNeeded to your view from within an animation block).
You can follow official Apple instructions:
- About Auto Layout and Layout Constraints
- Animating Layer Content
来源:https://stackoverflow.com/questions/36793287/uitableview-doesnt-shift-when-moving-from-textfield-to-textfield-directly