UITapGestureRecognizer in UITableViewCell are not recognized - ios

I made a quite a bit customized UITableView which has 3 rows, each row is custom made using UITableViewCell. I added several UIViews within UITableViewCell along with UITapGestureRecognizers.
Due to many small views in UITableViewCell, I implemented codes for touch events on "m" file of that UITableViewCell.
Somehow the recognizer are not working. I am not sure I am providing enough info here..
UPDATE: I realized my explanation isn't quite enough.. so a little more detail.
This is how my UITableView look like,
UITableView has UITableViewCell(A).
UItableViewCell(A)'s contentView is made by combination of 6 other UITableViewCells(B).
Each UITableViewCells(B) has a few UIViews which have those TapGesture recognizers.
I know it seems over complicated, but I used UITableViewCell(B) not for reuse purpose but for repeated Nib files. Anyway the final UIView doesn't take any touch events.

UITableView has its own tap gesture for selecting the row. You can do it by implementing your code inside following functions. Can you tell me what are you using to implement for selecting the row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}

Related

How to create a repeatable view in iOS and XCode

I am somewhat new to iOS, but am experienced in Android.
I have an app I am working on and it needs to populate a page with your "history" of past people you've interacted with, and it shows their picture, name, rating, and some other information.
This needs to populate in a vertical list, maybe a table? See the image below...
Now, in android, I would create a custom class with a layout that houses the picture, name, information, rating, and what not in one xml file, and in the activity I would call that class in a for loop, grabbing all the users and then programmatically it would add each view one after another, with their own unique user information until there is no more users to populate with.
How exactly can I do this in iOS and xcode? Do I need to make an XIB and add the picture, name, rating, and info place holders in that, and create a custom class for it that I would use to run in a for loop as well? I am a little stuck on how to do this with iOS.
Any help is much appreciated, and I can provide any additional information! Thanks :)
In iOS, you probably want to use a UITableView, with each row being a custom subclass of UITableViewCell. You can either create the layout for those cells in a separate XIB, or put the whole lot, tableView and "prototype" cells in a storyboard. You can achieve a lot without even subclassing, so fire up a dummy project in XCode and play (using one of Apple's templates gives you a good start). Enjoy.
What you probably want is to use a UITableView.
You don’t do the for-loop yourself. What you do is implement a set of delegate methods that the table view calls back to.
You can create your prototype cell in your XIB or Storyboard. When you add a Table View to the layout, you can then add a cell to that table view, and that cell will be your prototype. It looks like you only need one prototype cell, but you can create as many as you need. In Interface Builder you give the prototype cell a “reuse identifier”, which is just an arbitrary tag you use to refer to the prototype in your code. Your prototype cell can be your own subclass of UITableViewCell, or if you don’t need any custom code in it, you can just use UITableViewCell.
Then you implement several delegate methods. One is where you set the number of sections in the table view; it looks like you will only have on section.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv
{
return 1;
}
Then you tell it how many items are in the table view. Assuming you have the objects you want to display in an array, you just return the length of the array.
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section
{
return self.objects.count;
}
Then, for each item in the array, cellForRowAtIndexPath will be called. Make that method return the actual cell. You call dequeueReusableCellWithIdentifier to retrieve your prototype cell, using the reuse identifier you assigned in Interface Builder. Then use the corresponding object to set up the UI elements in your cell.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)i
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:i];
Thingy *item = self.objects[i.row];
cell.textLabel.text = item.name;
return cell;
}
That should be enough to get you started with the documentation, now that you have the overview of what you need to implement.
The first thing you have to do in switching from Android to iOS is to learn the terminology. Then you'll know what to search for on Google, SO, etc.
What's you're looking to do is create a UITableView.
Here is a link to a super basic 'how-to' to get you started with tableviews.
http://www.appcoda.com/uitableview-tutorial-storyboard-xcode5/
Once you've got the basics down, you'll want to take that a step further with learning how to customize the UITableViewCell within your tableview, so you can accomplish the look you've detailed in the question.
http://www.appcoda.com/customize-table-view-cells-for-uitableview/
I'm not sure I can help anymore than that at the moment. Jump in, learn tableviews, and start searching on OS to answer the million other questions you'll have a long the way.
Good luck!

How to create a view for settings of my iPhone apps in Xcode storyboard

I am new in iOS programming and I would like to create I view for the settings of my app that looks like iPhone's one (like in the picture). Some of rows will call other views when taped and other will not.
What is the best way to do that? I thought about TableView with prototype cells, but is there a best way to do it? or a best-practice for what I want to do? Or maybe a tutorial online?
The fast way in Interface Builder:
Use a UITableViewController, make it STATIC and use the GROUPED style (all in IB).
You can setup the cells to show disclosure indicators (or not) in IB also.
You can segue directly from the rows or the UITableViewController to where you want to go.
If you segue from the UITableViewController, implement the "didSelectRowForIndexPath" method and call "performSegueWithIdentifier" accordingly.
A structure like this is best by UITableView.
First you select how many sections you want, and customize each section with a data structure that you have to be filled with (Probably an array.)
Then you fill up each rows inside
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
method, and call your value from the array/dictionary that you have.
for going to a next view when clicked upon
Use the method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Hope this helps
The best way to do that is using static UITableViewCell.
See UITableView Programming.
The optimal solution here is undoubtedly UITableView. This is because firstly, you have the need to display a list of options that would have external links to other pages and UITableView is designed and used for this purpose.
In an addition to that, if you want, you can also expand and collapse the rows of your parent TableView into a Child TableView i.e a UITableView as a subview of its parent UITableView.
Put up a UITableView and populate it with UITableViewCell. That will be just fine with the requirement you have.
Hope this helps.

How to enable didSelectRow on selecting an element included inside the cell?

Well I have gone through web to search an easy implementation of this question but all I heard is coincide with what I thought at beginning which is not easy enough.
I was wondering if anybody could provide a better and easier implementation to solve this issue.
Well looking at the picture below, (Please neglect the crudeness of the picture)
I have a table view with multiple cells.
And based on the data, there will be different element(s) inside each cell.
If I touch inside the scrollview in cell 2 as shown in the picture. The delegate method for the tableView "didSelectRowAtIndexPath" will NOT be called, which is a problem for me.
So my first thinking is either to trigger the [tableView selectRowAtIndexPath] within the Scrollviews delegate method or I attach another tapGesture to these subviews and trigger it from there. But it already doesn't sound like a intuitive implementation and hard to maintain.
Anybody got any idea how could this be solved in an easier way?
Thanks
There are a wide variety of objectives you might be trying to accomplish here, so I won't speculate on the ultimate goal which you haven't told us, but in general:
If you would like two different UIElements to execute the same chunk of code, then you encapsulate that code in a stand-alone method, and call that method from both places.
In your UIScrollView as a subview of a UITableViewCell example, you would call it from within -(void)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath and you would also call it from the gesture recognizer that you attached to your scrollView.
I will speculate that the part you're having trouble with is knowing which scrollView was touched, or which row the scrollView was in. One possible approach would be to send the UIScrollView or the UITableViewCell as a parameter for the standalone method you created. -(void)doSomethingSpecialWith:(UITableViewCell*)cell or -(void)doSomethingSpecialWith:(UIScrollView)view
Post some more code, or feel free to explain your agenda further, but I have a strong feeling that the best way for you will be to subclass UITableViewCell, add the UIScrollView as a property of the custom cell, and wire up the gesture recognizer to call a method of your subclassed UITableViewCell.
i think the better way to solve this problem is :
creat custom method , - (void)tableviewSeletedIndexPath:(NSIndexPath *)indexPath
you can call this method in TableViews delegate -(void)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath , and call this method in your scrolls method.
Make the tag of scrollView is equal to the current cell row:
scrollView.tag = indexPath.row;
Make your ViewController to be the delegate of UIScrollView and in didScroll get the index and call didSelect:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSIndexPath *index = [NSIndexPath indexPathForRow:scrollView.tag inSection:0];
[self tableView:self.tableView didSelectRowAtIndexPath:index];
}

Adding rows to UITableView built from Storyboard

I have a static UITableView built from a Storyboard that works well. I want to fill the first category programmatically, though, from a user-defined file
Simply put, I want to go through all the strings in an array and add them as cells for the rows of the first category. For the second category, I have a series of mildly complex cells (containing a number of labels, textfields, buttons and other controls), defined in the storyboard, that I don't feel like recreating in code.
As far as I understand, the default behaviour for a UITableView built from a storyboard is to use the nib file as an implicit datasource. If I use a custom class as datasource, my second section doesn't work. I have thought of two possible ways to fix this:
Fill my first category from the datasource and delegate the rest to the nib file. Is this possible? Is there some method to programmatically ask the nib to fill my UITableView?
Export my storyboard-built cells into code and paste this code into my datasource. This method has the disadvantage of making my second category harder to modify.
Is one of those two options feasible? Is there another option?
I would use dynamic prototype cells. Then, I would set up the ViewController as the delegate and the dataSource. I would then create a custom subclass of UITableViewCell and connect the elements of the second section to IBOutlets in the custom UITableViewCell.
If the first section wasn't something that could be done with one of the generic cell types, I would also create a custom subclass of UITableViewCell for that section as well.
I would then use the cellForRowAtIndexPath: method to set up the cells with the information that I want in them. So if my first section used FirstSectionCell and my second section used SecondSectionCell as custom subclasses of UITableViewCell my cellForRowAtIndexPath: would look like this:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0)
{
FirstSectionCell *firstCell = [tableView dequeueReusableCellWithIdentifier:#"First Cell Prototype"];
//Set up the first cell.
return firstCell;
}
else if(indexPath.section ==1)
{
SecondSectionCell *secondCell = [tableView dequeueReusableCellWithIdentifier:#"Second Cell Ptototype"];
//Set up second cell.
secondCell.someLabel.text = #"whatever";
//etc.
return secondCell;
}
else
{
//if you have another section handle it here.
}
}
There are two kinds of table views when you use Storyboards:
Static
Dynamic
You're currently using the former. You define everything in the Storyboard and have very little code.
But you need to change to the latter.
You can still keep your UITableViewCells in the Storyboard; there's no need to do that in code (though you can if it makes things easier). You can refer to the template cells using the "reuse identifer."
Otherwise you've pretty much got it. You'll need to write code to implement the data source and (possibly) more methods of the table view delegate.
It's kind of fiddly switching from static to dynamic. I keep meaning to raise a Radar because I'm sure Xcode could be making it easier to do...

How to implement UITableViewCell without UITableView

I want to use the power of UITableViewCell like disclosure accessory, but I don't need the whole UITableView. Is this possible and appropriate to do so ? I don't see any delegate on UITableViewCell, so don't know where should I put code previously in - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath; any references or suggestions on this ?
Correct me if im wrong but .. Why would you use a cell like that ? If you dont want to use the power of the UITableView you can just add a view and do all the stuff you do in your cell. And that would keep the Apple Standard too.
You could just make a UITableView with one section and one row, and load that cell into it. This would be pretty easy to do and wouldn't run the risk of running afoul of the Apple review board.

Resources