Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pin one cell in a horizontal UICollectionView to the right

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.

Tag selection

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?

like image 288
Hélène Martin Avatar asked Sep 26 '16 11:09

Hélène Martin


1 Answers

Here is a solution where the UITextField is not part of the UICollectionView.

enter image description here

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)
            })
        }
    }

}
like image 195
Carien van Zyl Avatar answered Nov 15 '22 13:11

Carien van Zyl