ios - how to create an IBAction for a UITableView? - ios

I am not certain whether I need an IBAction for a UITableView, but what I am trying to do is have some sort of control that I can hide it during page load, and then populate its cells with data that I get from a remote server, and then display that UITableView.
How can I do that? When I currenly try to press control and drag the UITableView to the ViewController, it gives me optons of: dataSource or delegate. I chose dataSource, but then was not sure what to do next.
I tried to do something like this in the .h
#interface MyBusinessesController : UIViewController
- (IBAction)businessList:(id)sender;
#property (weak, nonatomic) IBOutlet UITableView *businessListProperty;
#end
and this in the .m
#import "MyBusinessesController.h"
#interface MyBusinessesController ()
#end
#implementation MyBusinessesController
#synthesize businessListProperty;
...
but it seems I am way off. What is the right way to do what I am trying to do?
Thank you!

If I understand your question correctly you want a UITableView to be hidden when the view loads and download some info from a server in the background then when all data is finished downloading display the table view? Why do you need an IBAction? In viewDidLoad set the "businessListProperty" table to hidden, self.businessListProperty.hidden=TRUE;
then use an NSURLConnection to download the info from the server and in connectionDidFinishLoading set the table view to whatever data you downloaded and then set its hidden value to false.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//set tableview to whatever you downloaded here
self.businessListProperty.hidden=FALSE;
}
-Shrdder2794

Related

UICollectionView Datasource Methods

UICollectionView has some built-in datasource methods, such as the "cellforItemAtIndexPath" method and the "numberofitemsinsection" method. If I understand correctly, these methods are called after viewDidLoad() completes. However, for my purposes, I want to be able to exactly control the point in time in which these methods are called. How can I do that?
The reason is that I am loading loading some images and I want to finish the task of loading before these methods are called.
It sounds like you don't want to show the collection until the images are downloaded, is that right? Does returning 0 for the number of items until the images finish downloading work? I don't have my Mac with me, or I'd test this before posting.
Disconnect the collectionView datasource and delegate connected to the controller from storyboard. Then set them in the code once you needed.
First connect the collectionView outlet to the interface section.
#interface YourViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate>
#property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
So once your images are loaded, call this method:-
self.collectionView.delegate= self;
self.collectionView.dataSource= self;
[self.collectionView reloadData];

Xcode - Update label text when button is pressed in other view

Newbie question for Xcode gurus...
I have two views. They both use the same custom class. In view_1 I have a button and when this is pressed view_2 will show. In view_2 I have a label which will have it´s text changed when I press the button in view_1. As of now the Label_1 is nil when I set a breakpoint at it and therefor useless. How can I get to update this label when I press the button? Her are some snippets from my code...
This is my .h file:
#interface ViewController : UIViewController
{
IBOutlet UIButton *buttonSelectTimeInterval;
IBOutlet UILabel *labelTimer;
}
#end
This is the button action in my .m file:
- (IBAction)startPouring_ButtonClick:(id)sender
{
labelTimer.text = #"foo";
}
…but my .m file doesn't seem to know the labelTimer since it is a ´nil´. Why is this so? It is instantiated in the .h file.
Anyone?
You can use NSNotificationCenter. Put this in you IBAction.
[[NSNotificationCenter defaultCenter] postNotificationName:#"buttonPressed" object:nil];
And this to your viewDidLoad.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(selectorhere) name:#"buttonPressed" object:nil];
somewhere in your .m
(void)selectorhere {
labelTimer.text = #"foo";
}
You can use NSNotificationCenter for this.
Here are the apple documentation link.
First, nothing is "instantiated" in the .h file - that's just the public listing of what properties and methods are available to other classes. Think of the header file as a table of contents, but only for the things the class wants others to see.
Those properties don't exist in memory until the instance of the class itself is created, and then only if you set them to some initial value once they're needed.
How & where are you creating the 2nd view? Is it a storyboard segue or something? The 1st view doesn't seem to have any way of knowing the 2nd one exists, so it won't be able to see or access the label.
View1Class.m
#import View2Class.h
#implementation View1Class
- (IBAction)startPouring_ButtonClick:(id)sender {
//Instantiate the 2ndView when you need it.
// This gives View1 a reference to View2 and its public UILabel.
View2Class * my2ndView = [[View2Class alloc] init];
my2ndView.labelTimer.text = #"foo";
}
#end
As I said, it's still not clear how/where you're actually displaying the 2nd view though, so the snippet above is incomplete. You could use a modal w/a delegate, or this is where NSNotificationCenter is a helpful option - the 2nd view can sign up to get notifications & change accordingly. There are numerous tutorials about creating a 2nd/modal view and displaying it on a button click - you should probably look at those to clarify how the structure of such an app ought to work.
This answer should get you on the right track.
Other specific issues:
Why is the label nil? Because there isn't one...
In this IBAction, which seems to be in View 1:
- (IBAction)startPouring_ButtonClick:(id)sender
{
labelTimer.text = #"foo"; //this is looking for labelTimer in the clicked view.
}
... it is looking for its own labelTimer IBOutlet (in which case it should probably be self.labelTimer.text), and not that of the 2nd view. If the 1st view doesn't even have a UILabel IBOutlet, this is another problem.
If the views have different functions & different properties, they probably shouldn't be instances of the same custom class. If the 1st view doesn't have or need a UILabel, it shouldn't have one in its .h. If the 2nd view doesn't have or need a button it shouldn't have one in its .h. If the views serve different purposes, then make them different classes.
BTW,
Since you're using instance variables for your IBOutlets, you'd need to write your own getter & setter methods if you want to change their values. Did you? To make those values accessible to other classes, you'd need to make those methods public & put them in the .h. It's not good practice for an instance to set its instance variables directly w/o a getter/setter, and other objects definitely should not.
The preferred method is to use #properties for your IBOutlets instead of declaring them as instance variables. This will automatically create the getter & setter methods, backing store in memory, and as of XCode 4.4 it automatically adds #synthesize so you no longer need to do so. Declaring your IBOutlets as "weak" references prevents retain cycles & memory leak, where the view holds on to the outlets & the outlets hold on to the view & nothing ever goes away...
View1Class.h
#interface ViewController : UIViewController
#property (nonatomic, weak) IBOutlet UIButton *buttonSelectTimeInterval;
#end
View2Class.h
#interface ViewController : UIViewController
#property (nonatomic, weak) IBOutlet UILabel *labelTimer;
#end

iOS Add a row to UITableView on button click from another ViewController

I am a new in iOS Development and I can´t move forwards... Is here somebody with experience, who can help me to solve my problem?
I use a Storyboard. First you see a ViewController with buttons. When you click on one of the button, informations about this button appear in a TableViewCell. - until now is it clear.
Than you click on a button "Continue" (than you come back to ViewController with buttons) and choose another button from ViewController.
HOW to do it, that informations from this button comes to a TableView as a second Cell? (so that when you click on for example three of the buttons, they appear as 3 cells under each other in this table?)
My Sample Code is here to download. - (on this website click on the smallest icon "Download").
Thank you very very much for your help!!!
Iva
You need a Model to store your selections/data.
For example: On MainViewController, when you click on button1, record that in the Model using array or just variable. Then, when you load SecondViewController, check the values in Model and load cells accordingly.
=> Example code for Model
// Header
#interface ModelData : NSObject
#property (nonatomic) NSMutableArray selectedProducts;
#property (nonatomic) NSInteger value1;
#property (nonatomic) NSInteger value2;
#property (nonatomic) NSInteger value3;
#end
// Implementation
#implementation ModelData
#synthesize selectedProducts = _selectedProducts;
#synthesize value1 = _value1;
#synthesize value2 = _value2;
#synthesize value3 = _value3;
#end
Various options:
Use NSUserDefaults to store information like settings
Use a Model class as described above - it could be a singleton class
Use CoreData to store and retrieve your data - complicated approach and suitable for dynamic things
Here is a reference to a good Data Model tutorial (reported by Iva)

UITableView inside a UIView

I would put an UITableView inside a UIView. I created a XIB where I have a tableView.
#import <UIKit/UIKit.h>
#interface PointsViewController : UIViewController <UITableViewDelegate>
{
IBOutlet UITableView *tableView;
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
[tableView setDelegate:self];
}
I instantiate the PointViewController class from another class and add it to a UINavigationBar by means of a button:when I click the button, the PointsViewController'view (the tableView) shall open. But it does not.
What am I missing? I tried also to make PointsViewController as a subclass of UITableViewController which works, but no UITableView is displayed.
You will also need to make your ViewController a delegate for UITableViewDataSource.
#interface PointsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *tableView;
}
#end
...and support the corresponding methods.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html
You need to also hook up the table's dataSource and delegate to the File's Owner. Otherwise the view controller doesn't know what table to send responses to.
In your XIB, select the table and open the Connection Inspector. Then drag the 'plus' sign next to dataSource to File's Owner to make the connection. Do the same for delegate and the table's referencing outlet.

Loading multiple tableviews in a UIView (UIView Controller)

I've been searching all throughout the internet for assistance, however there has been little to no solutions to my issue at hand. My project that im trying to get a gasp on is somewhat unique (UI is not exactly following the typical norms).
Current Development Enviroment:
xcode 4
storyboards instead of nibs
Below is a diagram of what i am trying to accomplish -- all within a UIView Controller:
UIView is the light grey background
UITableView 1 - this is a static (or it can be dynamic, thats another challenge) UITableview which will hold different numeric
values for calculation
UITableView 2 - this is a UITableview which will hold calculated results every time it is run.
UIImageView 1 - this is a calculated image example (I have that figured out)
Im sure experienced developers are fully aware of my issue, and or what im about to ask. I understand that a static UITableView is required to be in a tableview controller, but I need to display both the UItableView's at the same time which means it has to be within a UIView.
I can make the interface look the way I need it to through the IB however when trying to compile and build I receive the error that requires the UITableView's to be within a UITableViewController and not a UIView Controller. I have seen many examples using a master-detail layout, but the only stipulation is that this UITableview NEEDS to be displayed 100% of the time when in this view.
So basically, I am asking for direction... but a code example never hurt either! Thank you 100x's over!
-Jonathan
UITableViewController is just a specialized UIViewController specially designed to display full screen UITableViews. It is (quite) equivalent to use an UITableViewController subclass or an UIViewController <UITableViewDataSource, UITableViewDelegate> subclass to manage a tableview.
So even if UITableViewController has some more spiecialized behaviors (automatically creates the UITableView if it does not exists, scrolls it automatically to display the keyboard, sets itself as the delegate and dataSource of the unique UITableView it manages, etc), you can use a standard UIViewController to manage a UITableView and be its dataSource to fill it.
That's even a way to manage a tableview that is not taking the full screen (as UITableViewController expects its view property to directly be the UITableView it manages, not a subview of its main view or whatever, and thus expects the UITableView to take the whole screen, contrary to using an UIViewController that has an UITableView as a custom-sized subclass of its view)
So in your case, you can have an UIViewController that has two IBOutlets, one for each tableView, and that unique UIViewController can be the dataSource (and delegate) of both the UITableViews. That's not a problem. Just be careful then in your datasource methods to distinguish if you are returning data for the first or the second UITableView to feed the correct tables each time.
#interface MyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, retain) IBOutlet UITableView* masterTableView;
#property (nonatomic, retain) IBOutlet UITableView* detailsTableView;
#end
#implementation MyViewController
#synthesize masterTableView = _masterTableView;
#synthesize detailsTableView = _detailsTableView;
// Proper memory mgmt not shown here:
// - don't forget to set self.masterTableView and self.detailsTableView to nil in viewDidUnload
// - and to release _masterTableView and _detailsTableView in your dealloc method
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell;
if (tableView == self.masterTableView)
{
static NSString* kMasterCellIdentifier = #"MasterCell";
cell = [tableView dequeueReusableCellWithIdentifier:kMasterCellIdentifier];
if (!cell)
{
cell = [[[UITableViewCell alloc] initWithReuseIdentiier:kMasterCellidentifier] autorelease];
// do some configuration common to all your master cells
}
// configure the rest of your cell for each property that is different from one cell to another
}
else if (tableView == self.detailsTableView)
{
// Do exactly the same principle, but for the cells of your "details" TableView
}
return cell;
}

Resources