Within my collection view, when the cell is clicked to show the detailed view controller via a push segue, it crashes - apparently because of a breakpoint with a property connecting to an imageview.
The code is as follows - that's causing the problem.
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (nonatomic, strong) UIImage *image; // <--- break point.
#end
The segue identifiers are correct etc.
I started a similar thread but this post is more specific.
Related
I'm using Xcode to write an app in objective c. I am trying to pass data from a container view controller to the parent view controller using delegation. I have successfully passed the data to the parent view controller, but all of the documentation sets what I have sent to the .h header file in the .m implementation file using viewDidLoad or viewDidAppear. I was wondering, since the view is already present, if there is a way to detect that data has been changed in a view and automatically run a method or code to update the view with the new information. Something along the idea of didReceiveNewData or didEditExistingValues (of course those arent real methods). Thank you for your help!
Edit: What I have done so far:
I want to pass the data from MainFeedTableViewController to MainFeedViewController (The first is in a container inside of the second). I want to set the title of the custom navigation bar in MainFeedViewController to something described in the MainFeedTableViewController.
In the MainFeedTableViewController.m (the view sending data) I have:
#import "MainFeedTableViewController.h"
#import "FeedViewController.h"
#interface MainFeedTableViewController ()
#end
#implementation MainFeedTableViewController
- (IBAction)swipeLeftDetected:(UIGestureRecognizer *)sender {
UIStoryboard *mc = self.storyboard;
FeedViewController *fv = [mc instantiateViewControllerWithIdentifier:#"FeedViewController"];
fv.navigationBarTitleToSet = #"HOPING TO SET TITLE TO THIS";
[self performSegueWithIdentifier:#"MainToLocalFeed" sender:self];
}
and some other unrelated stuff..
In the MainFeedTableViewController.h I have:
#import <UIKit/UIKit.h>
#interface MainFeedTableViewController : UITableViewController
#end
In the MainFeedViewController.m (the one receiving the data) I have:
#import "FeedViewController.h"
#interface FeedViewController () <UINavigationBarDelegate>
#property (weak, nonatomic) IBOutlet UINavigationBar *navigationBar;
#end
#implementation FeedViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)setNavigationBarTitle:(NSString *)navigationBarTitle{
self.navigationItem.title = navigationBarTitle;
}
And in the MainFeedViewController.h I have:
#import <UIKit/UIKit.h>
#interface FeedViewController : UIViewController
#property NSString *navigationBarTitleToSet;
#end
I want to run the setNavigationBarTitle method with either data from the .h (navigationBarTitleToSet) or just from the sending view controller, if possible to run a method with delegation. Thanks a ton and I hope this is possible :)
It turns out I needed to add a second navigation bar to account for the container view, allowing me to navigate around the current stack with the parentViewController method and then navigationItem.title. For anyone who happens to find this with a container, make sure you add one immediately after the embed segue. I'm still not sure if you can use methods through delegation, but I can't ponder any situations where it would be necessary anymore, due to viewDidLoad. Thanks to #Tander for the help!
I know that there are several posts around the www, but sadly I don't get the tableView to be loaded.
here is my code:
.h file
#interface ViewControllerSzenenLichter : UIViewController<UITableViewDelegate, UITableViewDataSource>{
IBOutlet UITableView *tableView;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#end
I connected the IBOutlet with my tableview in the Storyboard
.m file
#interface ViewControllerSzenenLichter ()
#end
#implementation ViewControllerSzenenLichter
#synthesize tableView;
somewhere in the code I try to execute
[self.tableView reloadData]
which is executed(checked by Breakpoint)
but the method numberOfRowsInSection or numberOfSectionsInTableView are never called!
As mentioned I found a lot of tutorials in the web, but I can't solve the Problem.
thanks
Your child tableView is basically a cell of your parent tableView.
So, unless you reload your parent tableView, the cell will not update, and hence, the child tableView will not be plotted.
[childTableView reloadData];
[parentTableView reloadData];
EDIT :
And #Desdenova is right. Make sure you set your delegate and data source to self or whatever class manages the tables.
In the storyboard Right click over the table you will see datasource and delegates as the first two options.Connect both to the viewcontroller (same as you did for outlet connection) and run again.
The final table connections will be like this
It seems, you connect one IBOutlet and use another when reload data: You have two ivars tableView (you create it manualy) and _tableView (created compiler and links with #property (nonatomic, retain) IBOutlet UITableView *tableView;), I don't now which one will be shown as TableView property of file owner in InterfaceBuilder. Try remove IBOutlet UITableView *tableView; ivar and reconnect Table in IB
First of all, make sure you are setting delegate in xib file or implementation file for your table. If still not working, check the code where you are reloading table. If main thread is busy doing something else, it will not call any of the delegate method of UITableView. So when the code finishes, then reload tableview.
Connect your TableView to the File's Owner by the delegate and datasource...
I think your problem will be solved. Here is a picture for your batter understanding...
For some reason, i'm not able to change or add text in my UITextView from code.
I have made Outlet and connected (All in IB) - nothing happens.
Even tried to add -setNeedsDisplay
Do i need to set some property ? - This i driving me nuts....
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextViewDelegate> {
UITextView *textInfoView;
}
#property (nonatomic, retain) IBOutlet UITextView *textInfoView;
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
textInfoView.text = #"Test";
}
-(void)viewDidAppear:(BOOL)animated{
textInfoView.text = #"Test";
textInfoView.text = [textInfoView.text stringByAppendingString:#"Line2"];
[textInfoView setNeedsDisplay];
It seems, really strange that this code doesn't update the text inside the UITextView. I have tried and it works for me ... I think that you don't have correctly linked the Outlet in interface builder, or you don't have associated your view controller to your view ...
UPS - Got it...
Forgot to #synthesize...
For some reason i did not get warning or "setter error" in Xcode 4.4, maybe it's a version bug ?
In my project, there are two view controllers - let's say firstViewController and secondViewController. The second view controller has a button, and I want to make sure when the button gets pressed, the second view controller is telling somehow the first view controller - "hey, I got pressed, do something!", and it will do something, like changing a label. How is this possible to perform? Thanks in advance. Some code :
#interface firstViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *textLabel;
#end
#implementation firstViewController
#synthesize textLabel;
#end
#interface secondViewController : UIViewController
-(IBAction)buttonPressed;
#end
#implementation secondViewController : UIViewController
-(IBAction)buttonPressed{
// Hey, I got pressed! Set the text on textLabel to "OK"!
}
#end
This is a very simple case of delegation and protocol mechanism of objective-c..
have a look at this tutorial which will explain you how its done.. you can do this via notification also but that is not usually advised...(because notification is usually used when the receiver is unknown , like in the case of UIDeviceBatteryLevelDidChangeNotification you don't exactly know which view controller wants to know about this.)
I'd first consider what the button press means. Does it change the state of the model?
Say your model is an int, and the button increments it. The view controllers wouldn't message each other about that, they would just both observe the state of the model. (The one with the button could change the state, too).
Thinking about it this way, the solution probably isn't delegation. It's probably notification or KVO.
See the answer to this question: Passing data between two view controllers via a protocol
However, ask yourself if you really need a protocol here. If it is just between this classes or just about the question of accessing data of a class or sending information to a class then that is what the interface of a class is made for.
#interface firstViewController : UIViewController{
UILabel *textLabel; // I personally alway add IBOutlet here too, but I think that is not required.
}
#property (weak, nonatomic) IBOutlet UILabel *textLabel;
#end
And in SecondViewController.m:
#import "FirstViewController.h"
#implementation secondViewController : UIViewController
-(IBAction)buttonPressed{
// You will have to have a properly set instance variable firstViewController
[firstViewController.textLabel setText:#"OK"];
}
#end
So your second view controller needs to 'know' the first one. One way of achieving that is defining
FirstViewController *firstViewController;
as property and set it from wherever the second view controller is created and the first one is already known. How to do that exactly depends very much on the architecture of your app.
EDIT: Figured it out. I was able to access the property through the appDelegate instance with appDelegate.detailViewController.thisRequest = aRequest;
I'm porting a fairly simple iPhone Navigation based app to a Split View iPad app.
I have two nested levels of navigation on the Master view. The user picks a value from the first table and it loads the 2nd table. Selecting a value on the second table loads the Detail item for the detail view. Or it's supposed to. It's letting me set the property on the DetailViewController without an error, but it doesn't appear to be actually setting it. It's just null.
I'm following the SplitView template fairly closely. I'm only really getting off the beaten track by adding that 2nd TableViewController. My RootViewController loads the 2nd TableViewController on didSelectRowAtIndexPath, and that part's working. In my 2nd TableViewController.m I'm trying to set the detail item for the DetailView. In didSelectRowAtIndexPath I am able to get the object for my detail, but when I set it it doesn't set.
Here's the code:
First, in my DetailViewController, I set up a property for the object that will populate my fields (*thisRequest):
DetailViewController.h:
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
UIToolbar *toolbar;
Request *thisRequest;
}
DetailViewController.m:
#interface DetailViewController ()
#property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize toolbar, popoverController, detailItem, detailDescriptionLabel;
#synthesize thisRequest;
Then, in my 2nd TableViewController, I try to maintain a reference to the DetailViewController (I suspect this is where I'm messing up; I still don't fully understand how things persist and exactly how to reference them in this framework).
RequestsTableViewController.h:
#class TrackerSplitViewAppDelegate, RequestsTableViewController, DetailViewController;
#interface RequestsTableViewController : UITableViewController {
NSString* selectedDepartmentID;
NSMutableArray *requests;
DetailViewController *detailViewController;
}
#property (nonatomic, retain) NSString* selectedDepartmentID;
#property (retain, nonatomic) NSMutableArray *requests;
#property (nonatomic, retain) IBOutlet DetailViewController *detailViewController;
RequestsTableViewController.m:
#implementation RequestsTableViewController
#synthesize selectedDepartmentID;
#synthesize requests;
#synthesize detailViewController;
<snip>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TrackerSplitViewAppDelegate *appDelegate = (TrackerSplitViewAppDelegate *)[[UIApplication sharedApplication] delegate];
Request *aRequest = [appDelegate.requests objectAtIndex:indexPath.row];
detailViewController.thisRequest = aRequest;
NSLog(#"Request Loaded: %#", aRequest.Title);
NSLog(#"detailViewController.thisRequest: %#", detailViewController.thisRequest.Title);
[appDelegate release];
}
The aRequest object loads just fine, and the detailViewController.thisRequest = aRequest; line runs with no errors, but my log output looks like this:
2011-03-01 10:07:22.584 TrackerSplitView[8162:40b] Request Loaded: MyTitleString
2011-03-01 10:07:22.585 TrackerSplitView[8162:40b] detailViewController.thisRequest: (null)
Like I said, I still don't fully understand how everything gets passed around in the iOS framework, but the SplitNavigation template does something nearly identical to this with an id value and it works fine. The only differences I can see is the navigation layer isn't nested, as mine is, and also they don't use a pointer for the id since it's an integer instead of a custom object.
I'm guessing I'm not passing in the detailViewController to my RequestTableViewController properly, but I don't see how to do it.
EDIT: Figured it out. I was able to access the property through the appDelegate instance with appDelegate.detailViewController.thisRequest = aRequest;
On to the next bug.