i make my custom tab bar using segue it's run successfully , now i try to pass data between two view controller which is on tab bar view controller
my code for tab bar controller
- (void) perform {
ViewController *ctbcv = (ViewController *)self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
for(UIView *view in ctbcv.placeholder.subviews)
{
[view removeFromSuperview];
}
ctbcv.currentViewController = dst;
[ctbcv.placeholder addSubview:dst.view];
}
and segue condition
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"HomeSegue"]
|| [segue.identifier isEqualToString:#"DeveloperSegue"]
|| [segue.identifier isEqualToString:#"DesignerSegue"]|| [segue.identifier isEqualToString:#"btn4"]){
NSLog(#"%lu",(unsigned long)[self.buttons.subviews count]);
for (int i=0; i<[self.buttons.subviews count];i++) {
UIButton *button = (UIButton *)[self.buttons.subviews objectAtIndex:i];
[button setSelected:NO];
}
UIButton *button = (UIButton *)sender;
NSLog(#"%ld", (long)button.tag);
btnclicked = button.tag;
[button setSelected:YES];
}
}
this code run successfully, now i create button on 1st view controller and give segue to the new view controller , it's crash when click on button.
- (void)viewDidLoad {
[super viewDidLoad];
[btnnext addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(void) buttonClicked:(UIButton*)sender
{
NSLog(#"you clicked on button %ld", (long)sender.tag);
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
navVC *vc = [segue destinationViewController];
}
}
After this code it crash and Xcode show "THREAD 1: EXC_BAD_ACCESS(code=2 , address = 0xc)" any solution ?
i use this reference for making custom tab bar
i make button which open new view controller in this tab bar.
Thank You
just check out that u have put your code in the main controller that you wants to use and not in tabs of tab bar controller.
Related
when I come the part of sending image from UICollectionViewController to another ViewController here is View A:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Detail Segue"])
{
PhotoDetailViewController *PhotoDetailVC = segue.destinationViewController;
NSIndexPath *path = [[self.collectionView indexPathsForSelectedItems] lastObject];
Photo *selectedPhoto = self.photos[path.row];
PhotoDetailVC.photo = selectedPhoto;
}
}
and I receive it in the ViewController (View B) using:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.imageView.image= self.photo.image;
}
I think the problem is that you didn't call performSegueWithIdentifier:sender: in any place in code which actually responsible for triggering navigation not prepareForSegue:sender: which is called when preparing for the navigation
so I suggest to implement collectionView:didSelectItemAtIndexPath: as the following
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
Photo *selectedPhoto = self.photos[path.row];
// this line is the one that is responsible for navigation
[self performSegueWithIdentifier:#"Detail Segue" sender:selectedPhoto];
}
and modify prepareForSegue:sender: as the following
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Detail Segue"]) {
PhotoDetailViewController *PhotoDetailVC = segue.destinationViewController;
PhotoDetailVC.photo = sender;
}
}
I'm working on an iPad app where I use UISplitViewController. I also use DetailViewController in which to display some information from XML, but the information is not displayed in DetailViewController but in MaterViewController. I really do not know how to fix it. Can you please help. Thank you
There is code:
-(void) showDetailsForIndexPath:(NSIndexPath*)indexPath
{
[self.searchBar resignFirstResponder];
DetailViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailsViewController"];
Slova* slova;
if(isFiltered)
{
slova = [filteredTableData objectAtIndex:indexPath.row];
}
else
{
slova = [self.slovoArray objectAtIndex:indexPath.row];
}
vc.slovoItem = slova;
[self.navigationController pushViewController:vc animated:true];
}
The reason is that you're pushing the new UIViewController onto the stack for self, which is presumably the MasterViewController. Instead, create a new project using Apple's Master-Detail Application and you'll see how they do it.
Caveat: they use Storyboards, but it is very possible to do this all in code.
In Apple's example, both the MasterViewController and the DetailViewController are visible from the start (in landscape).
Look how Apple's example sets detailItem (slovoItem?) for DetailViewController:
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}
So, you'll have DetailViewController already visible and you'll just update its detailItem property.
Therefore, the following code exists in DetailViewController:
#pragma mark - Managing the detail item
- (void)setDetailItem:(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) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
Can someone tell me why my values are not being sent from a UIViewController to a UITableViewController?
In my UIViewController I have a number of buttons created programatically and each button has its own tag number set as below:
bySeaButton = [UIButton buttonWithType:UIButtonTypeCustom];
bySeaButton.tag = 4;
bySeaButton.frame = CGRectMake(20, 294, 280.f, 40.f);
UIImage *seaButton = [UIImage imageNamed:#"gettingHereBySeaButton.png"];
[bySeaButton setBackgroundImage:seaButton forState:UIControlStateNormal];
[self.view addSubview:bySeaButton];
[bySeaButton addTarget:self action:#selector(bySeaButtonClicked) forControlEvents:UIControlEventTouchUpInside];
Then in my prepareForSegue I set the tagVale in my UITableViewController to the buttons tag number as follows:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
MyTableViewController *vc = [[MyTableViewController alloc] init];
vc.tagNumber = bySeaButton.tag;
}
A NSLog here shows that the vc.tagNumber is set to the buttons tag number. However, when I access the value for the tagNumber in the UITableViewController, it is always set to 0. Below is how I use it (tagNumber is declared in .m of UITableViewController as #property (nonatomic, assign) int tagNumber;)
NSString *strFromInt = [NSString stringWithFormat:#"%d", self.tagNumber];
Output for this is always 0 - regardless of the buttons tag value
try this code in preparesegue
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
MyTableViewController *vc = segue.destinationViewController;
vc.tagNumber = bySeaButton.tag;
}
first declare segue id in storyboard ,after add this method in target
[self performSegueWithIdentifier:#"push segue id" sender:self];
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"push segue id"])
{
MyTableViewController *vc = [segue destinationViewControlle];
vc.tagNumber = bySeaButton.tag;
}
}
I have 2 views
1) A
2) B
When I segue from view A to view B, it takes a long while to load, so I added an activity indicator in the segue.
My problem is, when I segue over to view B, my screen freezes(loads) in view A and only for a split second, it shows the activity indicator before going onto view B.
How do I make sure the activity indicator appears before it starts to load.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[self useActivityIndicator];
if ([[segue identifier] isEqualToString:#"ShowAdsDetail"])
{
//do anything that needs to be done
}
}
-(void)useActivityIndicator{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[activityView startAnimating];
subView.hidden = NO;
}
I had a similar issue with a UIActivityIndicator that was animating too fast. The segue was pushing the next view controller right away and barely showing the activity indicator.
In case this can help others - I was able to fix it by implementing performSelector:withObject:afterDelay and then, in the removeSpinner method, calling my performSegueWithIdentifier method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
[self.spinner startAnimating];
[self performSelector:#selector(removeSpinner:) withObject:self.spinner afterDelay:2.0];
}
- (void)removeSpinner: (UIActivityIndicatorView *)spinner {
[self.spinner stopAnimating];
[self.spinner removeFromSuperview];
[self performSegueWithIdentifier:#"showMyPlans" sender:nil];
}
Just change your code like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self useActivityIndicator];
});
if ([[segue identifier] isEqualToString:#"ShowAdsDetail"])
{
//do anything that needs to be done
}
}
-(void)useActivityIndicator
{
dispatch_async(dispatch_get_main_queue(),^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[activityView startAnimating];
subView.hidden = NO;
});
}
Is this piece of code suppose to set the title on the ViewController I am connecting to?
The 2 UIViewControllers are connected via a push segue - the first one is embedded in a NavigationController.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"settingsSegue"])
{
self.navigationItem.title = [[NSString alloc] initWithFormat:#"Custom Title"];
}
}
It does not work for me, but the syntax is right.
Advance Thanks:-)
The above answer works for me with one exception...
Change
self.title = myTitle;
to
self.navigationItem.title = myTitle;
Set the title in the viewDidLoad of the destination viewcontroller using a property in the destination VC:
if ([[segue identifier] isEqualToString:#"settingsSegue"]) {
MyDestinationViewController *mdvc = segue.destinationViewController;
mdvc.myTitle = [[NSString alloc] initWithFormat:#"Custom Title"];
}
Then in the viewDidLoad event in MyDestinationViewController.h:
#property (nonatomic,strong) NSString *myTitle;
In MyDestinationViewController.m:
#synthesize myTitle;
And finally in viewDidLoad:
self.title = myTitle;
You can set the title directly in the segue as well, there is no need to go through a property:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"settingsSegue"]) {
segue.destinationViewController.navigationItem.title = #"Custom Title";
}
}
Or, what I needed, to set the title of the pushed view controller to the title of the table cell that was clicked:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"settingsSegue"]) {
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:myIndexPath];
segue.destinationViewController.navigationItem.title = cell.textLabel.text;
}
}