UICollectionView prepareForSegue tapping UIImageView by gesture - ios

I used a UICollectioView to load Images with a NBMutableArray from web and working well.
Now adding a Tap Gesture Recognizer on my UIImageView and i will pass the information to other view like a segue identifier example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([#"getImage" isEqualToString:segue.identifier]) {
NSIndexPath *index = [self.collectionView indexPathForCell:sender];
[[segue destinationViewController] setLinkImg:(arrayCollectionImages)[index.row][#"image"]];
}
In MyStoryBoard i used this:
if I leave only this function my app go to crash when tap on image.
any body know how can do that?

No need to add Tap Gesture Recognizer to UIImageView. Just connect 'Triggered Segues' of CollectionCell to your destination ViewController. So that sender will be CollectionCell in
*- (void)prepareForSegue:(UIStoryboardSegue )segue sender:(id)sender method.

:)
obviously it will crash.
it will search the method "setLinkImg" on details page where you need to show this.
so make sure this method is active on details page where you are going to show image.
and again check also the collection array should contains any value
so in details page where you need to show image should contain
Code should be there in details page
- (void) setLinkImg:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
your-imageview-object.image = [uiimage imagename:self.detailItem)];
or any url should set on image view object.
}
}
let me inform if any need

Related

get tableView of a UISearchBar

I have an UISearchBar in on top of my TVC. If the search is active it displays another tableView on top of the normal tableView (this is normal). Now i need to get the "searchTableView" in prepareForSegue() because I need to call:
var newIndexPath = table.indexPathForSelectedRow!
and this fails if you search something.
I also can't do the decision in didSelectRowAtIndexPath() because the segue is called to fast because it is 'linked' directly to the UITableViewCell. I also tried to create the segue from the ViewController but this also fails because the segue needs to end on the same ViewController again.
So basically I want to ask if anyone knows how to solve the error in the Code line above will doing a search.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath;
if (self.searchDisplayController.active)
{
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
}
else
{
indexPath = [self.tableView indexPathForSelectedRow];
}
// Use the indexPath...
}

Either WebView or another View

I am new to iOS development and also have a mentor, that helps me most of the time, but he isn't available at the moment.
So I am planning on doing an app from a JSON feed (easiest app idea I could come up with). But the page the JSON feed is about supports posts that either have an url or a comment (also the attributes in the JSON file). So if a comment is available, the post doesn't contain a url. But also the other way 'round: If a post contains a url, there is no comment in it.
What I want to do now is checking if the current post that is clicked on the UITableView has a comment or a url and then switching to the WebView or to a normal View.
How to do this one? Because I connected the UITableView with the View where the comment is displayed through Storyboard.
My current prepareForSegue looks like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *story = stories[indexPath.row];
NSNumber *storyId = story[#"id"];
[[segue destinationViewController] setDetailItem:storyId];
}
}
Set up a datasource for your table view and then in the tableView:cellForRowAtIndexPath: method check if your post has a URL or comment. Based on which one it is you can create the correct view and add that view to the UITableViewCell's contentView.
Something like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Create your cell
UIView* contentView = nil;
if (<isURLPost>)
{
contentView = <CreateAndSetUpYourWebView>;
}
else
{
contentView = <CreateAndSetUpYourOtherView>;
}
[cell.contentView addSubView:contentView];
}

uiLabel in another viewcontroller is not updated when uicollectionview cell select

I placed an UIcollectionview in a viewcontroller (working successfully).
I want to open another viewcontroller and update the label in this vc with the selected cell text.
I am using following code but it's not working (not updating the label in other vc):
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// gorseldetay is another viewcontroller including a label and an image
NSLog(#"Row : %d , Section : %d", indexPath.row, indexPath.section);
[self performSegueWithIdentifier:#"showDetail" sender:self];
gorselDetay *g = [self.storyboard instantiateViewControllerWithIdentifier:#"gorselDetay"];
NSLog(#"%#",g.mylabel2.text); // returns "null"
g.mylabel2.text = #"any text to update";
NSLog(#"%#", g.mylabel2.text); // returns "null"
}
and I also added prepareForSegue action
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"%#", segue.identifier); // returns "showDetail", OK
if ([[segue identifier] isEqualToString:#"showDetail"])
{
UIImage *imageim2 = [UIImage imageNamed:#"anyimage.png"]; //this file exists
gorselDetay *r1 = (gorselDetay * )[segue destinationViewController];
[r1.mylabel2 setText:#"any text to update"];
r1.gorselim.image = imageim2;
NSLog(#"2 - %#", r1.mylabel2.text); // returns "null"
}
}
As I said above, UICollectionView is successfully populated and working OK but the label in another viewcontroller (named gorselDetay) is not updated. But gorselDetay vc succesfully opens by the way.
Thanks for any help.
You can't update a label (or other UI elements) this way from another controller because its view hasn't been loaded yet (r1.myLabel2 will be null). You need to pass the text to a string property in r1, and then set the label's text with that property in r1's viewDidLoad.

prepareForSegue getting called twice, with Attempt to present <UINavigationController> while presentation is in progress

I am new to ios programming and asking here, but I visit all the time! I am stumped at why I am getting this problem, it compiles with no errors and I have checked and checked all my outlets and identifiers in my MainStoryboard.
I have 2 UITableViewControllers, I am passing a string from the first to the second when the user selects an item in the table, so in
FirstTableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int sel = indexPath.row;
if (sel == 0) {
_keyName = [NSString stringWithString:_string1];
NSLog(#"the table was selected at cell 0, %#", _string1);
}
if (sel == 1) {
_keyName = [NSString stringWithString:_string2];
}
// more code below...
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ResultsSegue"])
{
UINavigationController *navigationController = segue.destinationViewController;
ResultsViewController *rv = [[navigationController viewControllers] objectAtIndex:0];
[rv setResults: _keyName];
NSLog(#"in the progress view, %#", _keyName);
//rv.delegate = (id)self;
rv.delegate = self;
}
}
And in my ResultsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"in the results, %#", _results);
NSLog(#"in the results view");
}
In the NSlog readout I get:
...
in the progress view, (null)
in the results, (null)
in the progress view, The Right String
Warning: Attempt to present on
Then when I hit the cancel button to return to the firstTableview and press the detail view again it no longer shows null..
in the progress view, The Right String
in the results, The Right String
in the progress view, The Right String
The problem is prepareForSegue is called before didSelectRowAtIndexPath. You should just eliminate the didSelectRowAtIndexPath method, and do everything in prepareForSegue. You can use the following line to get the indexPath you need:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Rob's answer helped me, as well - thanks! I'm coding in Swift, so for those who run into this while Swifting, here's how to get the index (or index row) clicked on in Swift 3:
var rowClicked = (self.tableView.indexPathForSelectedRow?.row)!
May be your segue is connection start form the table view cell instead of view controller.
I had same issue I removed the segue from the table view cell and added back at view controller level.

UITableView only sending data to Detail View Controller on Second Try

Hey there I have been working on a transit app for some time and have been stuck with this issue for a while now.
I am using iOS 5 and a storyboard. Basically I have a UITableView that displays favorite bus stop locations, when a user selects a row I use:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Favorite *favorite = [self.favoriteItems objectAtIndex:indexPath.row];
stopString = favorite.title;
routeString = favorite.subtitle;
}
With the stop and route information of the cell the user chose I then prepare for a segue that corresponds to a segue on my storyboard, pushing a detail view controller that uses the stop name and route name to display times from a plist.
I am fairly new to Objective C and iOS so I am using a segue that my friend told me would work, however, it might be the problem. The segue looks like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destination = segue.destinationViewController;
if ([destination respondsToSelector:#selector(setDelegate:)])
{
[destination setValue:self forKey:#"delegate"];
}
if ([destination respondsToSelector:#selector(setSelection:)])
{
NSString *route = routeString;
NSDictionary *selection1 = [NSDictionary dictionaryWithObjectsAndKeys:route, #"route", stopString, #"stop", nil];
[destination setValue:selection1 forKey:#"selection"];
}
}
After the segue in my DetailViewController I grab the stop and route information in the view DidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
route = [selection objectForKey:#"route"];
stopName = [selection objectForKey:#"stop"];
NSLog(#"stopName: %#", stopName);
NSLog(#"routeName: %#", route);
}
Here is where my problems arise. When I run the simulator and click on an a cell in my table view, I am pushed to the DVC, however, the stopName and routeName are both null, so no information was sent or received. BUT, if I go back to the table and click another cell, the routeName and stopName are filled with the information that should have sent the first time I clicked a cell. If I continue this process it continues to send the information for the cell tapped previously, not currently.
So basically information is sending but only after I go through the segue twice. Obviously I want it to send the information and receive it the first time, but it is delayed and driving me nuts. I appreciate any help someone can give me as I have been searching the internet for days now trying to fix this issue, thank you so much in advance for any assistance!
prepareForSegue: is being called before didSelectRowAtIndexPath:. This is why the values you see always are lagging behind.
The better solution is to get the stopString and routeString values in your prepareForSegue: method (and not use didSelectRowForIndexPath: at all). The key to doing this is to realize that the sender parameter value being passed to prepareForSegue: is the UITableViewCell that was tapped. You can use the UITableView method indexPathForCell to get the cell's indexPath in your table, and then use that to look up the data in your favoriteItems array.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UITableViewCell *cell = (UITableViewCell*)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
Favorite *favorite = [self.favoriteItems objectAtIndex:indexPath.row];
stopString = favorite.title;
routeString = favorite.subtitle;
UIViewController *destination = segue.destinationViewController;
if ([destination respondsToSelector:#selector(setDelegate:)])
{
[destination setValue:self forKey:#"delegate"];
}
if ([destination respondsToSelector:#selector(setSelection:)])
{
NSString *route = routeString;
NSDictionary *selection1 = [NSDictionary dictionaryWithObjectsAndKeys:route, #"route", stopString, #"stop", nil];
[destination setValue:selection1 forKey:#"selection"];
}
}
Make sure that you are NOT connecting the segue to the next view controller to the tableView CELL directly. Connect to the whole UITableViewController / UIViewController (whichever you are using) and give a name, say "segueNameInStoryboard".
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Favorite *favorite = [self.favoriteItems objectAtIndex:indexPath.row];
stopString = favorite.title;
routeString = favorite.subtitle;
/* add this line */
[self performSegueWithIdentifier:#"segueNameInStoryboard" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"segueNameInStoryboard"])
{
UIViewController *nextViewController = segue.destinationViewController;
nextViewController.delegate = self;
NSDictionary *selection1 = [NSDictionary dictionaryWithObjectsAndKeys:routeString, #"route", stopString, #"stop", nil];
nextViewController.selection = selection1;
}
}

Resources