I am implementing a control that behaves like an NSTokenField
(the address picker in Mail, for example) for use in iOS. I use a horizontal UICollectionView
and my rightmost cell is a UITextField
. This control will appear in a form with other textfields that have right-aligned text. For my new control to look right in this context, I'd like for the UITextField
to always be at the right edge of the UICollectionView
and for selected tags to appear to the left of it.
At the moment, when I first click into this row, the textfield scrolls to the left and then it gets pushed to the right as more tags are added. Once it is flush with the right edge of the UICollectionView
(when 'Appetizer' is added in the image below), then I start getting the behavior I want.
I've been thinking about something like a minimum width on the UITextField
so it takes up as much width as is available at first and less and less as tags are added. Or alternately, some way to pin the fixed-with field to the right. I haven't found a way to implement these ideas, though!
How can I make it so the textfield is always at the right of the UICollectionView
?
Here is a solution where the UITextField is not part of the UICollectionView.
I added the collectionView and textField on my storyboard with the following layout constraints: CollectionView: Leading to superview, Height, Top to superview, horizontal spacing with textField. TextField: Height equal to collectionView, Trailing to superview, Width = 100, horizontal spacing with collectionView.
I created an IBOutlet for the width constraint of the textField. The width is changed dynamically as text is entered.
Swift 3 Sample Code
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var textFieldWidthConstraint: NSLayoutConstraint!
var textArray: [String] = [String]()
@IBAction func editingChanged(_ sender: AnyObject) {
let size = textField.sizeThatFits(textField.frame.size)
textFieldWidthConstraint.constant = max(size.width,100)
if textArray.count > 0 {
self.collectionView.scrollToItem(at: IndexPath(row: self.textArray.count-1, section: 0), at: .right, animated: true)
}
}
@IBAction func addText(_ sender: AnyObject) {
if textField.text?.characters.count ?? 0 > 0 {
textArray.append(textField.text!)
textField.text = ""
textFieldWidthConstraint.constant = 100
let newIndexPath = IndexPath(row: textArray.count-1, section: 0)
collectionView.insertItems(at: [newIndexPath])
collectionView.performBatchUpdates({
}, completion: { (_) in
self.collectionView.scrollToItem(at: newIndexPath, at: .right, animated: true)
})
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With