I want to use UIWebview like UITableView . A single webview should contains data like tableview. how can i track which data is tapped like didSelectRow in tableview
You should convert the table cell like html view clickable, with the link pointing to something that can be identified later in the code.
your view
In your iOS code implement the delegate to identify the above link been clicked.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{
if ([request.URL.host isEqualToString:#"rowclicked"]) {
// Perform row clicked
return NO;
}
return YES;
}
Related
I have programmed in several other languages but this is basically my first ios app and I am struggling to correctly implement a UITableView.
After reading the documentation, the most common way to accomplish this is to create a class that is a subclass of UITableViewController. I have done this and I have implemented all data source protocol methods as well as the row selection method from the delegate protocol and gave it three properties.
The first one is the number of rows in the tableview,
the second is an array of the items to be displayed as labels in the table view,
and finally there is a property to hold the text of the label from the selected row.
Once the row is selected, I set the property of that holds this label and then I remove the table form the view with [self.view removeFromSuperView].
The above isn't the only view in my app. The app is a color picker assignment, from school, so the main view contains all of the controls to manipulate the displayed color.
What I did after subclassing UITableViewController was, create an instance of this subclass in my main view controller and made it a property. So, on the main view is a recall button that allows the user to choose from a list of previously saved colors. When this button is clicked the this IBAction method is called
-(IBAction)swithToSavedColorsView:(id)sender {
self.savedColorTable.numberOfRows = self.dictionaryOfSavedColors.count;
NSLog( #"Count in switch view is %d", self.dictionaryOfSavedColors.count );
[ self.view addSubview:self.savedColorTable.view ];
}
This presents a list of the available saved colors and I respond to the row selection with
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
self.textFromColorSelection = [ [ NSString alloc ] init ];
UITableViewCell *cell = [ tableView cellForRowAtIndexPath:indexPath ];
self.textFromColorSelection = cell.textLabel.text;
NSLog(#"The value of selection is %# ", self.textFromColorSelection );
[ self.view removeFromSuperview ]; // Go back to main screen.
}
As I was writing this code I was getting an erie feeling that I went about the creation of the UITableView in the completely wrong way from the beginning. Please let me know if I am doing something wrong as far as how I have communication between these objects set up.
The problem I am actually trying to solve is in the above method after i call
[ self.view removeFromSuperView ], how will my other view know when this has happened? What I want to do when the UITableView closes is have my other view get the label property from the instance I created and use that label to retrieve information out of a database.
Thanks for the help, it is greatly appreciated.
If you need several controllers to respond to the dismissal of the table, you will likely want to use NSNotificationCenter in viewWillDisappear or viewDidDisappear. More likely you are presenting from a viewController and only that viewController is waiting to learn what color was selected. I would suggest handling that with a delegate/protocol pattern.
Add something like this to your color pick table myColorPickTableController.h file above the #interface line:
#class myColorPickTableController;
#protocol myColorPickTableControllerDelegate
-(void)myColorPickTableControllerDidSelectColor:(UIColor *)selectedColor sender:(myColorPickTableController *)sender;
#end
Add a property in that header as well, to store reference to the delegate (the controller which is waiting to hear what color was picked).
#property(nonatomic, unsafe_unretained)id<myColorPickTableControllerDelegate> delegate;
Now, replace the line
[ self.view removeFromSuperview ]; // Go back to main screen.
with
[delegate myColorPickTableControllerDidSelectColor:[UIColor whateverColorWasPicked] sender:self]; // Tell main screen user picked a color
Now in the presenting controller, you need to conform to the protocol by adding to your interface line
#interface myPresentingController : UIWhateverControllerIAm <myColorPickTableDelegate> // Add that part between <>
Now, in myPresentingController.m you implement the method
-(void)myColorPickTableControllerDidSelectColor:(UIColor *)selectedColor sender:(myColorPickTableController *)sender
{
[self saveTheSelectedColor:selectedColor];
[sender.view removeFromSuperview]; // I am not so sure about that, should be presenting, maybe modally or use navigation controller. Should work thought, not my first choice.
sender = nil; // Just for good measure
}
Lastly, remember to make your presenting controller the delegate of the myColorPickTableController when you create it. Set delegate as self like so
myColorPickTableController *pickTable = [myColorPickTableController alloc] init];
pickTable.delegate = self.
In your subclassed UITableViewController, viewWillDisappear and viewDidDisappear should be called after your view is removed. Try sending a notification when your view disappears (look into NSNotificationCenter).
I am new to iOS Development and Objective-C in general. Currently I am working on an app that contains 3 tabs. As you can see from the screenshot below the first tab contains a Table View with 2 cells.
So, after the user taps on one of the cells another detail view appears with buttons which later will be changed with pictures of the products that are going to be listed there.
My question is: How do I connect the buttons with another view that will contain a table view with some details?
What you need is a Grid View to display your products. Use GMGridView. Its brilliant...
In your storyboard, hold down the control key and drag from your cell to the view controller you want to connect it to. Then set the segue style to "push." Set the name of your new segue. Then in code set the product data in the -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// GET THE SELECTED ROW
NSInteger selectedRow = [[self.tableView indexPathForCell: sender] row];
// PASS THE CORRESPONDING DATA TO THE NEXT VIEW CONTROLLER
if (segue.identifier isEqualToString: #"MySegue") {
MyViewController* myvc = (MyViewController*)segue.destinationViewController;
MyProductData* selectedData = [_productData objectAtIndex: selectedRow];
myvc.productData = selectedData;
}
}
So once the user taps a product image button, you want to display more detail about that item?
In your image grid view controller, just create a method:
- (IBAction)imageButtonAction:(id)sender {
// do something like check the [sender tag]
// to determine which button sent the message
// then instantiate the detail view controller and push
}
then connect this method to the Touch Up Inside action in Interface Builder. Rather than a proliferation of action methods for each button, you could give each button a tag and route all of their Touch Up Inside actions to the same method.
My app has a "favorites" tab. Inside, of course, there are the items (in a UITableView) that the user has set to "favorite".
My problem is this: when, at the starts, the user has no favorites, i want to show an UIView (with an UIButton "add favorite") and not the UITableView...
is it possible?
Sure, it will be a simple conditional in your code, preferably within the viewWillAppear: method. Something like the following:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (self.hasFavorites) {
// add UITableView as a subview
} else {
// add UIButton as a subview
}
}
Yes, this is possible. I'm assuming you have the user's favorite store in some kind of Array. So simply:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Reload the array here.
[self loadFavoriteArray];
if (_favoriteArray == nil || [_favoriteArray count] < 1) {
[_favoriteTableView setHidden:YES];
[_noFavoriteView setHidden:NO];
}
else {
[_favoriteTableView setHidden:NO];
[_noFavoriteView setHidden:YES];
}
}
How is your view set up - UIViewController or UITableViewController? If I understand your question correctly, I think you have a couple options.
1) You could set the tableHeaderView. This would allow you to have a button above the table which could be populated with a single cell that reads 'No Favorites'...or something like that. Would allow you to remove the button if they have a favorite listed, or you could even leave it there for good as a quick way to add additional favorites
2) Assuming your using a UIViewController (and subsequently adding your UITableView), and not UITableViewController, you could simply just not add the UITableView subview if they don't have any favorites.
Hope that helps...
I have a UITableViewController that is the detail view for another UITableViewController.
On this table is a cell labeled "Date". Using Apple's "DateCell" example (http://developer.apple.com/library/ios/#samplecode/DateCell/Introduction/Intro.html), I have tried to add a UIDatePicker when you touch the cell.
I have wired up everything exactly the way the example does. The only thing I've changed is that I fenced the didSelectRowAtIndexPath code in this:
if(indexPath.section == 1 && indexPath.row == 0)
{
//Date picker stuff
}
This is to ensure it only runs when the right cell is pressed.
For the life of me, I can't get it to work. Clicking it does nothing but turn it blue (selected). Clicking it repeatedly does nothing.
If I scroll to the bottom of the UITableView, clicking it animates up a white rectangle. Clicking repeatedly eventually covers the whole table view.
It doesn't make a lot of sense to me. Please..how can I do this?
If you want more code, I can provide it, but it's virtually identical to the DateCell code. I copied/pasted for the most part.
Thanks in advance,
Clif
Make sure you have a picker object in IB if that's what you are using, then create an IBOutlet reference and connect it to the IB object. I set my pickerView to hidden in IB and make it visible when required. Otherwise you can simply instantiate one as needed.
In your didSelectRowAtIndexPath, you can try the code below and see what happens.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (**your cell/section selection logic here**) {
[self.view endEditing:YES]; // resign firstResponder if you have any text fields so the keyboard doesn't get in the way
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; // Scroll your row to the top so the user can actually see the row when interacting with the pickerView
// Pickerview setup
[self.typePicker setCenter:CGPointMake(150, 500)]; // place the pickerView outside the screen boundaries
[self.typePicker setHidden:NO]; // set it to visible and then animate it to slide up
[UIView beginAnimations:#"slideIn" context:nil];
[self.typePicker setCenter:CGPointMake(150, 250)];
[UIView commitAnimations];
}
}
After that you need to implement your pickerView:didSelectRow: method if you want to update the label of your cell as the picker view selection changes...
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// Your code to get the current table view cell and update it with the data from your pickerView
}
Make sure your viewController is declared as delegate for the tableView <UITableViewDelegate> as well as for the pickerView `'
This should give you a good head start. Let me know if you have any questions etc.
Cheers,
Rog
I've implemented edit menu from my custom UITableViewCell class. I have a small problem of updating a table view from inside the custom table cell class. What is the best approach to do that?
TIA
Clarification: By edit menu I meant a standard Cut/Copy/Paste... menu, that can complies with a standard UIResponder protocol. I want to cut/copy/paste cells content, which resides in some data structure (kind of folders/files tree). The cell actually only reflects the data.
The menu shows up on tap & hold on table cell. The table is derived from UITableViewController and created on fly (not from the xib). Cut/Copy actions are allowed for folders & files, while Paste action is allowed only for folders. Actually I need to refresh only the folder cell, which shows the number of items inside.
So in my CustomCell in paste selector I do the following:
- (void)paste:(id)sender {
... Perform a paste of data...
MyTableViewController *myTable = (MyTableViewController *) delegate;
[myTable performSelector:#selector(updateData) withObject:nil afterDelay:0.3];
}
In MyTableViewController:
- (void) updateData
{
[self.tableView reloadData];
}
The thing is that all cells except of the one that was changed are redrawn. I see it in cellForRowAtIndex function. Even if I add in paste selector [self setNeedsDisplay] it doesn't help.
Also, my custom cell overrides setHighlighted function:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
if (delegate)
[delegate copyableTableViewCell:self willHighlight:highlighted];
[super setHighlighted:highlighted animated:animated];
}
so the delegate (MyTableViewController) shows an edit menu there.
And again the question is why the changed cell doesn't refresh?
Thanks
Do you want to update a single cell or the whole tableview? What about some kind of delegates, or selectors?
Resolved. Calling in MyTableViewController:
- (void) updateData
{
[self.tableView performSelector:#selector(reloadData) withObject:nil afterDelay:0.3];
}
and it does the work...