NIB File Doesn't Display at Runtime - iphone

I am pulling my hair out on this one. I have a NavigationController with two levels of TableViews. Each TableView is in its own NIB file. The first level simply displays a list. Upon selecting a cell, it takes the user to a second level TableView with a more detailed list. It is on this second level TableView that I want to display a search bar (actually I am using a SearchDisplayController as well). I have added it to the TableView because I want the SearchBar to scroll with the table.
Below, I am displaying two screenshots. The first is the second level tableview in InterfaceBuidler. The second is the second level tableview at runtime. For some reason, the SearchBar doesn't display at runtime.
I have tried creating a completely new project from scratch and the same things happens. I don't understand why the SearchBar doesn't display on a NIB pushed on the NavigationController.
Before you ask, if I put the SearchBar on the first level TableView, it shows up just fine. Yes, I am adding it to the TableView itself, so it is a part of the view that should be displayed.
Help! What am I doing wrong?
This is what actually displays after the XIB is pushed...

Okay, I'm going to have to answer my own question. I thought about deleting it, but perhaps this could help someone else. I really pulled my hair out on this one. It wasn't because of anything I was doing wrong so much as a fundamental misunderstanding of how iPhone development works.
In a nutshell, the problem was with this line of code, which instantiated the TableViewController:
self.downloadDetailViewController = [[DownloadDetailTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
When you use XCode to create a new class, you can use the following:
"Add -> New File -> Cocoa Touch Class -> UIViewController subclass -> UITableViewController
subclass AND With XIB for user interface"
The problem is that the NIB has absolutely nothing to do with the UITableViewController until you tell your code to use it. To me, this seems like a bug in XCode or at the very least something that is counterintuitive. When the development environment creates all three files together, it would only make sense that they would work together, but they don't.
Instead, the solution is to modify the line of code as follows:
self.downloadDetailViewController = [[DownloadDetailTableViewController alloc] initWithNibName:#"SecondaryView" bundle:[NSBundle mainBundle]];
Hopefully this can help someone else...

You could also set Nib Name property on your Download View Controller under the Tab Bar Controller, in fact that and coupled with setting the class with your class name will automatically create the view for you and you don't have to manually create it.

I think the problem is that you are adding the searchbar to the tableView, so it is not displaying.
Try to add that searchBar with out adding to the table view, that means move the table view some what down and add the search bar to the view(not the tableview).

Related

ViewController for Second View - iOS 7

I'm a beginner to iOS development, so forgive me if this is really basic. It's probably answered somewhere, but I've looked for a long time, and I'm struggling.
I have a second View on my story board that I've successfully linked to the first view using a Navigation controller and stuff, and I'm able to navigate to it. I can also add actions/outlets from elements on my first view by Control-dragging to the .h file.
I have a label on my second view, and I want to be able to do the same: add actions and outlets from elements. But when I try Control-dragging, nothing happens. What am I doing wrong, and how do I fix it?
Hmm, well first of all welcome to Stack Overflow! And thanks for asking the question.
Let me know if I have this right - you have two view controllers to the right (linked with segues) of a navigation controller and currently you can navigate to the second from the first using a button at the top right? Then when on the second view controller there's a nav button at the top left with a little arrow by it? And this should take you back to the first. Is that right?
Now on the second view controller you want to create a button that performs an action, but when you right-click-drag (ctrl-drag) onto a .h or .m file nothing happens?
If that's the case I've seen a few reasons for that. You might try:
You need to make a button, a label can only recieve actions, not create them. Read this article on IBOutlet vs IBAction
Restart Xcode (I know, it's lame, but humor me)
Make sure you're dragging (if on the .h file) between "#interface" and "#end"
Make sure you're dragging (if on the .m file) between "#implementation" and "#end"
Do you have a custom view controller class for your second view? If so, select the second view controller in your storyboard and go to the identity inspector. Set the custom class to your custom view controller's class name. Now you will be able to control-drag IBOutlets and IBActions.

ios, code-reuse issue, reuse viewController?

I have a view controller(A) which shows a list of items download from server.
I have another view controller(B) with segmented control.
When second index of segmentedControl is selected, the view controller(B) shows a list of items in the same format as in the controller(A).
When first index of segmentedControl is selected, the view controller(B) shows the items in different format.
I want A and B share a code for the common stuff.
I first thought ok I could move all the view-related code to "common_view class" and use the view class from both controllers.
But, it turns out that there are codes which are not related to view(such as downloading stuff from server, which is controller-part of mvc pattern).
Now I'm perplexed, "is it a good idea to share a controller-part code? is it even possible?"
I could factor out a common code into a commonViewController, and instantiate it from controller(A) and controller(B), and add commonViewController.view as a subview.
But is this really desirable? or do you suggest any better way to do this?
Yes definitely..you can.Use two NIBS in this case.The first NIB wil be used by ViewController A and first segment of ViewController B.On selection of second segment in ViewController B addSubView of viewControllerA which initsWithSecondNiB name.Once you have added them ,control their visibility by show/hide when toggling between between the two segments of viewcontrollerB

Making too many transparent views makes complicated in iPhone

Before Starting I want to make sure one thing whether we can make the ViewController transparent (alpha), as far my knowledge it is NO.
I have a ViewController which consists of 8 UIButton objects over it. Whenever I press Button1, Button2 I am loading a ViewController. Since the ViewController cannot be made transparent, I just moved that View to my HomeViewController.xib and I am loading the view using -addSubView:. And I am changing the alpha value to make it as transparent.
But the thing is in Button1 View and Button2 View, in both views I am having table view. When I bring everything to the same HomeViewController class , I am having too much of code in a single class.
Is there any way to do this?? Adding many Views in the same ViewController not a problem, but it increases the code too. Which looks ugly. Please help me out.
If I have confused about my question here I am giving a short description of what I would like to do
Whenever I press a Button in ViewController, I want to load a View/ViewController Transparently.
Before Starting I want to make sure one thing whether we can make the
ViewController transparent (alpha), as far my knowledge it is NO.
You can't adjust a view controllers alpha directly. You can adjust a view controllers view properties alpha, ex: myViewController.view.alpha, and you can do this for any view that you want except for your root view (the bottom of the view stack). Lowering your root views alpha would allow the user to see the springboard through your app.
But the thing is , In Button1 View and Button2 View , in both views I
am having table view. When I bring everything to the same
HomeViewController class , I am having too much of code in a single
class.
Is there any way to do this ?? Adding Many Views in the same
ViewController not a problem, but it increases the code too. Which
looks ugly. Please help me out.
I'm not sure I understand the problem here. As long as you format your code correctly and keep well organized this isn't a problem. I personally have used view controllers in excess of 15k lines of code and never had a problem, and I'm sure there are developers that have used way more.
If I have confused about my question here I am giving a short
description of what I would like to do Whenever I press a Button in
ViewController , I want to load a View/ViewController Transparently.
Continue the way you have been describing. (adding alpha adjusted UIView's as subviews) There is nothing wrong with this approach.

reuse view from storyboard

I have a tableview with custom section headers. The view for the section header is defined in the storyboard and wired to an instance variable. Is there a way to request a new instance of the view from the storyboard?
In the past I have done this by having the section header defined in its own xib file and getting a new instance by using
[[NSBundle mainBundle] loadNibNamed:#"TimerViewSectionHeader" owner:self options:nil];
UIView *newHeaderView = self.sectionHeaderView;
I dont' think there is a way to do that. Best bet is to put the tableview custom header view in a separate nib and load it like you did in your code sample whenever you need to use it.
I tried to do the same thing and ran into the same problem.
I like to work with storyboards a lot and was impressed how fast I could create a working UI. However, as soon as you need to re-use views it makes a lot of sense to put those into a separate nib along with its UIViewController subclass.
You can then place a generic UIView in all the places where your re-used view should go and add the view using your ViewController:
[myReusableViewController loadView];
[myReusableViewController viewDidLoad]; // You have to handle view callbacks yourself.
[self.myReusableViewPlaceholder addSubview:myResusableViewController.view];
[myReusableViewController viewWillAppear:YES];
So to sum it up:
Use storyboard, it's great
Create the scaffold of your application in the storyboard, along with any static view (like About screens etc.)
Create re-used views in a custom nib + UIViewController subclass and add UIView placeholders in your storyboard.
In another answer I thought about some Pros and Cons of Storyboard
The solution I've come up with for this is as follows:
I have a tableview with multiple prototype cells that displays complex data. There is a segue to a detail view, and a transaction process view.
This first tableview has a search button that displays a new tableview with the results. It needs the same functionality as the main tableview that pushes it; including segues to the detail and transaction progress views so:
On storyboard, select and copy your main tableview. Deselect and paste. Create a push segue from your main tableview to your 2nd tableview; or from where ever you want to navigate to it from. Modify the 2nd tableview as you like. IE: If it requires some UI changes no problem.
Create a new viewcontroller class that is a subclass of the viewcontroller running the main tableview.
Override the data delegate in your subclass to serve up the subset of data you want.
Back in the storyboard, select your 2nd tableview controller and in the identity inspector select your subclass as the custom class.
For this solution to work smoothly, your app really needs to be managing data for the views. You could use prepareforsegue to pass data from 1st tableview to the second, but I've found the app data model far more flexible from numerous points of view.
Unless you have buttons that push to the sub views via segue, your subclass will need to override functions that push via segues with identities. NB Segues must have unique identifiers if you id them at all.
It took a lot of trial and error to figure this out, but once you understand the concept, it's a relatively smooth solution that is quite adaptable and not so bad to implement.
I am not sure about just views, but the way that I was able to get view controllers out of my storyboard is as follows.
UIViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"IdentifierName"];
From here, perhaps you might be able to use this similarly to how it was once done with nibs.
I've been able to reuse a view in the storyboard just by connecting a transition from one tableview into the one I want to reuse.
so my tableview that I want to reuse is pointed to twice.
It sort of works but the problem I'm running into it setting a variable (using instantiateViewControllerWithIdentifier) in my app delegate to my table view that is getting reused.
It seems that if I reuse it, the storyboard is creating 2 instances of my tableview and the one I get with instantiateViewControllerWithIdentifier isn't the one I want.
I'm not really sure if this is the proper way to do it. But I assume many others are doing this somehow. With the custom table cells in storyboard I suspect lots of people want to reuse their views.
For example: We want to reuse the view(include subviews) in storyboard shown below.
The best solution I know so far is clip and paste the view related code to the New Singe View file without losing the information.
Detailed steps are as follows
Step 1: Rename the view we want reuse. Just prepare for step 2.
Step 2: Open storyboard as source code in order to clip the XML code we need
Step 3、4: Search and clip the code we need
Step 4.5(Not needed): Open as Interface Builder to see the view removed
Step 5、6: New XXX.xib and paste the code we clipped just now
Step 7: Important. Insert code<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> to XXX.xib source code.
Warning: Do this before open it as Interface Builder! Otherwise, you will see wrong size and layout waring.
[![step 7][9]][9]
Step 8: New XXX.swift to connect the XXX.xib
[![step 8][10]][10]
Step 9: Add the view anywhere we want
[![step 9][11]][11]
I get warning: "You need at least 10 reputation to post more than 8 links."
Can you support me to upload the remaining 3 screenshots?

UITableView scrolling crashes App

Preface: I am new to the iPhone SDK, Obj-C, Interface Builder and Cocoa. I'm likely doing something obviously wrong.
Question:
I have a UITableView which crashes if I scroll it. It will scroll a little to reveal the full cell of the bottom most half-hidden cell, but won't load the next one. Similarly, if I scroll past the top to fully hide the bottom most cell, and it rubber bands back to show that cell, it will crash before showing it. This strikes me as odd because it is drawing the first 7 of 11 cells correctly. The cell data is in an NSArray, in a UITableViewController linked as both the dataSource and delegate for the UITableView in Interface Builder. It works when the view initializes.
I'm making an App I thought I'd be done with 2 days ago that just calculates combinations and displays a list of them in what I thought would be a convenient scrolling table view. Right now, it doesn't even calculate everything, the NSArray in the DataSource is initialized once with some strings like #"Hello" and #"World".
Steps to reproduce:
Because I'm using IB, I can't exactly show you the full story in code. So I'm going to describe what I did so far and hope it doesn't make you sleepy.
Made a new "Tab Bar Application" in Xcode, because I want 2 tabs, and I don't want a nav bar nor a full screen table. I moved the MainWindow.xib's first tab view out into FirstView.xib as an analogue to the given SecondView.xib. This worked nicely. I modified the view to contain two UITextFields for inputs, and a UITableView for output. This worked but the table was empty. I subclassed the UITableViewController wherein I populated an NSArray property named combinations with 11 strings, and then added
// Set up the cell...
cell.userInteractionEnabled = NO;
cell.text = [combinations objectAtIndex:indexPath.row];
where there had only been the comment. In IB I added a Table View Controller to the FirstView.xib and set it's class name to match the name of this new subclass, and control-dragged the Table View in my view onto this Combinations Table View Controller twice. Once linking the dataSource and once the delegate. Although I get the same behavior if only the dataSource is linked.
This runs and populates the table's visible rows (6.5) with the first 7 values in the dataSource combinations. I can scroll 0.5 cells down, and then back up. But if I scroll more than 0.5 cells up or down the app will crash. The explanation in the report reads:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSCFTimer tableView:cellForRowAtIndexPath:]:
unrecognized selector sent to instance 0x52ca40'
I didn't make an NSCFTimer nor did I link it to my Table View, I suspect that the cellForRowAtIndexPath is exactly a message that should have gone to my dataSource or delegate so I'm confused at why it went astray and where it ended up going.
Update: Thanks for the answers and comments. My problem seems to be that the CombinationsTableViewController (subclass of UITableViewController) is actually not instantiated any particular place in my code. It does get created as some time (when the FirstView.xib is loaded) and is apparently managed while the initial tableView is filled with 7 cells, and is then released. So I need to identify where/how to make a retained reference to this controller. My Application Delegate should probably have some outlet that holds this controller that can be linked as the instance which is in the xib. Yeah, I'm new to this. I know I could just eliminate these troubles by avoiding the IB and doing things explicitly in code, but I figure I want to learn to use the IB flexibly.
Finally: Yes, I needed a retained instance of the table view controller. It sounds elementary, but this wasn't clear when working with the IB as I had. Read my own post for the whole process and fix.
Aside: Either the debugger needs detailed instructions (any links appreciated), or it doesn't work very well. I seem to get more information more quickly by letting the App crash and reading the report it generates. But this requires a tedious termination, relaunch, and 3 clicks. I had really wanted to move on from this to wiring up the inputs, doing the calculation, and updating the table with each change. That's supposed to be the hard part, not this making a framework member work stuff.
Further rambling: This was all in the iPhone SDK for 2.2.1. At the time iPhone OS 3.0 non-beta was not available yet without joining the club for cold hard cash. I expected it to be at the open of WWDC 2009, but it was actually today (July 17th 2009) that the free public 3.0 SDK was made available.
looks like you are losing your tableView delegate.
What looks like it is happening is the UITableViewDelegate is getting released and the app is then using the same pointer address for an NSCFTimer.
Have you called release on your delegete anywhere, or have you not retained the delegate if it is in an autorelease pool.
Okay so, if you followed the steps to reproduce I will now add the steps to solve this:
Steps to fix this problem
Subclass a UIViewController. I called mine CombinationsViewController. In this controller add a property as an IBOutlet for the combinationsTableViewController from step 6 below.
Don't forget to import the right stuff, and synthesize the table view controller, also release it in the dealloc method.
In FirstView.xib change the File's Owner class to this latest subclass.
Link it's combinationsViewController outlet to the Combinations Table View Controller in the FirstView.xib made in step 7 below.
Open the TabBarController in your MainWindow.xib select the first tab, and in the Identity Inspector change the class to the latest subclass (CombinationsViewController).
That makes the table populate normally and scroll stuff.
Now I'm going to move on finally and get some custom table view cell stuff happening and actually make my app do stuff.
Enumerated Steps to reproduce as a reference to the fix:
Made a new "Tab Bar Application" in Xcode.
Opened the Tab View Controller, dragged the prefab view for the first tab out into the MainWindow.xib
Made a new view based xib called FirstView.xib as an analogue to the given SecondView.xib, and put that prefab view into this xib.
Linked the view to the File's Owner's view outlet.
I modified the view to contain two UITextFields for inputs, and a UITableView for output.
I subclassed the UITableViewController as CombinationsTableView wherein I populated an NSArray property named combinations with 11 strings, and then added the cell.text = [combinations objectAtIndex:indexPath.row]; code where there had only been the comment about setting up the cell.
In FirstView.xib I added a Table View Controller and set it's class name to match the name of this new subclass, and control-dragged the Table View in my view onto this Combinations Table View Controller twice. Once linking the dataSource and once the delegate.
At this point the table does render with data, but the scrolling breaks. This is because the CombinationsTableView isn't retained anywhere. And that's very unclear to a first time IB user. So you need to apply the fix listed above.
The first person to summarize this in their answer get the correct answer check mark. E.G. Make a viewController subclass that is the file owner of FirstView.xib and contains an retained IBOutlet you can link to your table view controller in the same xib file.
The reason the first cell loads, is because the tableview pre-loads that like the other cells that are on screen.
All cells are loaded from the datasource method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I would make sure that you have explicitely set the delegate and datasource of the tableView. This can be done in code or IB. by:
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
Also as Bluephlame said, you might be releasing the UITableVewController somewhere.
To find out, set a breakpoint inside the dealloc method:
- (void)dealloc{
//releasing things
[super dealloc];
}
If you do release it, you will hit this breakpoint. Then you can start to track down the culprit.
allocate memory to array instead of [NSArray arrayWithObjects:];. Without memory allocation it wont reload rows....use array=[NSArray alloc] initWithObjects]; ...instead of the above.
I had the same issue and fixed it by adding nil into an array as the last item.
It was crashing for this:
pairs = [[NSArray alloc] initWithObjects:#"EUR/USD",#"USD/JPY",#"GBP/USD",#"USD/CHF",#"USD/CAD"];
but not for this:
pairs = [[NSArray alloc] initWithObjects:#"EUR/USD",#"USD/JPY",#"GBP/USD",#"USD/CHF",#"USD/CAD",nil];
Hope this helps.
I had this same problem. I had a UITableViewController sub-class in a nib file, but I had only declared the UITableView as an outlet/property, which the tableview's UITableViewController was getting released while still in use.
The quick fix was simply to add an outlet to the File's Owner class that referenced the embedded UITableViewController.