Combine UIPickerView and UITableView - 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.

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.

IGListKit: get the currently visible cell index

I am trying to use IGListKit (Link) in iOS to render custom collection view and table view, where I have a horizontal scrollview in a section controller. In this horizontal scrollview, I need to get the index of the currently visible cells.
I tried to use the displayDelegate in the section controller, but it seems to me that the following delegate method is triggered only once when the section controller is initially loaded:
func listAdapter(_ listAdapter: IGListAdapter, willDisplay sectionController: IGListSectionController, cell: UICollectionViewCell, at index: Int)
So I was wondering if there's a way in IGListKit to get the index of the currently visible cells. Thanks!
Did you checked IGListAdapter's Visible Objects and Visible SectionController functions?
https://instagram.github.io/IGListKit/Classes/IGListAdapter.html#/c:objc(cs)IGListAdapter(im)visibleSectionControllers
self.section provides the index of currently visible cell.

How to transfer a variable from table cell class to another view through button

I am using Parse and Swift. I have a news feed with posts and each post has an ID. I have a variable that shows the current post ID. I have Navigation views set up in storyboard and when you push a comment button on a post it goes to the comments view.
I have functions set up to get the comments and the only thing I don't have access to is the post ID. All of the questions I find on here say to do an override func to pass the variable to the new view controller, but it doesn't work within the table cell and that is the only place I have access to the post ID. It works to transfer a variable from one UIViewController to another but I need to pass it from the Table View Cell class.
From what I have read you can only pass a "tag" through a button which I think has to be Int, and my ID is a string and always has letters and numbers. I hope this was specific enough, please let me know if I have to include any other information. I have spent several days trying to get this working.
Are you using a UITableViewController? Its easy to link a cell to the item it is representing with a reference to the UITableViewDatasource's.
func indexPathForCell(cell: UITableViewCell) -> NSIndexPath?
If it is a button in a cell find out what the button's superview is, ,Usually the cell's but you can keep going up until you find a UITableViewCell subclass, and then use the cell to find the indexPath.
A helper function on the Datasource to get the data for cell's indexPath may also be required

How do you reuse a UIPickerView?

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.

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