How do you reuse a UIPickerView? - ios

I have a UITableView with 13 cells.
I need to select options for each using a Picker Wheel but I don't want or think I need to create 13 View Controllers with nothing but a Picker Wheel on the VC.
I'm guessing I can use just one view controller to do this. Can I use else-if statements and reuse the same View Controller with the UIPickerView on it?
That way I would only have 1 View Controller to Segue to and one .swift file linked to it instead of 13 VC's and 13 .swift files.

Almost all the UIKit tools are built for reusability. What you need to be looking at is UIPickerViewDataSource and the UIPickerViewDelegate protocols. Conforming to these protocols will force you to implement the methods required to send the pickerView data.
There are a few methods associated with these protocols, all of them play a part in customizing some aspect of the table and will be useful in modifying what the user will see on the table. For example:
optional func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!
is the method that lets you modify the 'titles' (contents of each row) of the UIPickerView scroller.
In your case, to display different data using a single pickerView, you will put the if statements inside this method to manipulate what this method sends back to the pickerView.
What you want to do is have some kind of mechanism to differentiate which of the 13 piece of information you want to use in the pickerView, which you would handle in the aforementioned method.

Related

Swift Button That Outputs UICollectionView Cells One by One?

I made a UICollectionView, and everything is working. It makes 100 cells that I can scroll through in simulator with no problem.
However, rather than seeing all the cells at once, I want the cells to be released one by one whenever that red button is pressed.
I am confused because I noticed in the storyboard, it hard codes the number of cells it has on the screen at once. Is there any way to get around this?
Thank you!
This is what the UI looks like in storyboard.
This is the code I used to make it. It's basic, and just says to fill the text box of the cell with a string from the array.
Your question is garbled.
A collection view has a delegate and a data source. The data source responds to messages in the UICollectionViewDataSource protocol. That protocol lets the collection view ask how many sections it has, and how many rows in each section, as well as asking for the cells from those sections and rows.
There are also methods that let you tell the table view that you want to add more cells. Take a look at the method insertItems(at:). That lets you provide an array of indexPaths, which tells the table view that you have added new entries.
You could certainly write a button action method that added one or more entries to your data model and then used the insertItems(at:) method to notify the collection view that it had new entries. If there was room in the content view of the collection view to display additional cells it would then call the data source and ask for new cells at those index paths.
Sounds like you just need to keep track of how many items you want displayed (which will increase the more that button is pressed) and use that in your UICollectionViewDataSource method. Something like:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return min(myRunningItemCount, maximumNumberOfItems) //assuming there's a maximum
}
Then you just need to call reloadData on the collection view whenever that number changes.

Combine UIPickerView and UITableView

I'm trying to show information about a word in a UITableView. Originally I used labels in a view controller that were specifically spaced. Once I started using autolayout, that became too complex. That configuration also had the limitation of having a set amount of space to show info. Some of the information depends on the state of a UIPickerView. I tried putting a static table view in place of the labels but I got an error Static table views are only valid when embedded in UITableViewController instances. I tried to place the UITableView in a UITableView controller and embed that controller in a container view.
I don't know how to update the tableview contents when the picker view selection changes. I tried calling performSegueWithIdentifier("nounDetailTableViewSegue", sender: self)which is the embed segue, at the end of the func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {} function with the hope of updating the labels in the static table view.
I never got it to work, so is there a correct way of doing this.
A solution using the container view is too complicated. Its better to use a dynamic cell even if it's overkill.

Get selected value from UIPickerView custom delegate & data source

So I cannot provide you with any code, but it's quite simple what I want to achieve.
I am searching for a way to get the selected value from an UIPickerView in iOS 8 (Swift)
these pickerviews have a custom delegate & data source.
So the method of didSelectRow is accessed in a custom class, not the ViewController, but I would have to be able to get the selected value and use it in the ViewController. Let's say, place it in a textbox.
I can't find a way to do this, should I try to access the delegate itself or what should I be doing?
Care to share your knowledge with the students of Application Development? :)
The UIPickerView class has a method named: `selectedRowInComponent'. This function may help you select components in a picker view. Apple Documentation for UIPickerView class would help you with your project.
Also make sure your view controller conforms to the UIPickerViewController Delegate and Data source.

Swipe to remove on UIPickerView

Is there a way to implement a "swipe to remove" action on UIPickerView, just like it's done with UITableViewController?
I've been searching for this for some time, but have no solution.
UIPickerView objects are not editable. When in doubt, check the documentation: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPickerView_Class/Reference/UIPickerView.html
However, there's no reason why you couldn't make a custom UIPickerView using a UITableViewController and a bit of clever code to figure out which cell is in the middle and properly highlight it.

Can two UIPickerView objects share the same datasource array?

I have used Interface Builder in Xcode 4.02 to add two UIPickerViews in a View. They are connected to the same delegate and datasource (UIViewController). In my .h file I have also declared UIPickerViews and connected them as reference outlets, as in many examples.
In viewForRow I use the same NSMutable data array of UILabels to return the appropriate values (this array was populated in viewDidLoad).
However, I find that no Label appears in both UIPickerViews at the same time. For example, when the app starts each UIPickerView should show elements 0, 1 and 2. viewForRow is invoked 3 times for each UIPickerView but only the view which invokes viewForRow second will display the first 3 rows. The other UIPickerView is blank. If I scroll the first view down to, say, the 6th element and then back to the first, the view will then show the first 3 elements but the second view (the one that did show the first 3 rows) now shows nothing. Specifically, no data array element will appear in both UIPickerViews at the same time.
Is this expected? Should each UIPickerView have its own backing array - if you're using them? Aren't all these returned views just pointers? It's as if each array element can only be displayed (pointed to) at most once at any time.
If I use two separate data arrays then there appear to be no problems. But it does mean extra memory and extra coding.
Note: in viewForRow I have code to set the label's size:
UILabel *xx = (UILabel *)[self.array1 objectAtIndex:row];
CGSize rowSize = [thePickerView rowSizeForComponent:component];
CGRect labelRect = CGRectMake (0, 0, rowSize.width, rowSize.height);
[xx setFrame:labelRect];
The values set here do not change even when the row later appears to be blank.
Multiple picker views can share the same data source but a view (UILabel in this case) can only have one superview.
You cannot use the same labels in both pickers and there's probably little reason to store them in an array of your own anyway. A better approach would be to create a separate label in the viewForRow method and have just an array with the labels' content (e.g. an NSString).
In your current implementation, when you return the label, the picker adds it to its own view hierarchy which implicitly removes it from any view it was in before (your other picker).

Resources