I'm looking into creating a simple iPhone app without using the interface builder, i.e. without creating the XIB files.
I've succeed so far in showing the main window and changing the background color, but i'm looking into adding UITextfield, UILabel, and a button. and then connect them to methods that i've created before.
is there any good tutorial or a reference that I can use?
Thank you very much
Read Apple's documentation. For example, to create a UILabel programmatically, read the UILabel Class Reference. First instantiate it
UILabel *label = [[UILabel alloc] init];
Then set it up as you like, e.g.
[label setText:#"My label now has text!"];
Then add it to the view
[self.view addSubview:label];
Then move it around, etc. For more help, first google "create uilabel programmatically", then, if you get stuck, post a specific question here.
Related
Can't seem to find a way to fix a graphic - a light graphic that would remain static as the user navigates from scene to scene. Have been combing forums for a few days, but most answers point to MainWindow.xib, which isn't generated for a storyboard project. Would appreciate any advice.
Here’s what I was able to cobble together thanks to advice from #Max. Like I said, very new to this, so if this code needs tuning please leave a comment so I don’t lead others astray.
Add the image to the app’s main window in the AppDelegate’s didFinishLaunchingWithOptions method :
UIImageView *myGraphic = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myGraphic.png"]];
[self.window.rootViewController.view addSubview: myGraphic];
[self.window.rootViewController.view sendSubviewToBack: myGraphic];
Then, to make your views transparent so the background shows through - in your viewController class/es, add to viewDidLoad method:
self.view.backgroundColor = [UIColor clearColor];
(And note if you try to decrease the transparency through the alpha property for the view via the Attributes Inspector, it will make everything transparent on that view -buttons, etc - that’s why it needs to be done programmatically.)
Sure, it’s not thoroughly tested. But for now it’s working and it’s a thing of beauty. Thanks all.
You can try to manually add UIImageView to your window and then set 0 background transparency
for all other views.
One way to do it -- it may not be the best -- can be that you subclass a UIView, and set the UIView instance in all of your viewControllers in the storyboard an instance of your cutomized UIView class, which contains your graphic as a background.
If you're going to tackle this programmatically, within each view controller, set:
[[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
in viewDidLoad
I'm sure some tweaking would allow you to apply this principle throughout the program from the app delegate, or by using a singleton.
Using this solution, though, you're still going to have to make some method call within each view controller where you want this style applied.
I was really impressed, and really grateful about the answers I recived last time I asked here.
I have this problem with Core Plot.
I want to have a CPTGraphHostingView inside my UIView so I can have things like labels and scroll views below it.
I am using XCode 3.2 by the way.
How do I do this programmatically? Or with the Interface builder if possible.(I need the instructions to be detailed as im I bit new to this sort of thing)
Thanks for your support.
If you want to add a core plot graph to a UIView you have to add a CPTGraphHostingView as a subview to the UIView. In the example below, hostingView is a UIView and graphObject is a CPTXYGraph.
CPTGraphHostingView *graphHostingView = [[CPTGraphHostingView alloc] initWithFrame:hostingView.bounds];
[hostingView addSubview:graphHostingView];
graphHostingView.hostedGraph = graphObject;
Simple adding CPTGraphHostingView as a subView of UIView [programatically] didn't work for me.
I have searched through many threads and at the end I tried the simplest way to do this - I have created new UIView in interface builder and in this view I have created another UIView and change it to CPTGraphHostingView. Now I can simply create chart [like in tutorials] and link its main UIView anywhere I want.
I don't know why this didn't work programatically but it works from Interface Builder.
I use Xcode 4.2 and Core plot 1.0
What I want to do is a navigation bar with a image on it. I have a tab controller on my main view, and inside each tab I have a UINavigationController. From inside the UIViewController that my tab/navigationController calls, I could set the titleView without much problem, doing this inside the viewDidLoad method:
self.navigationItem.titleView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mylogo.png"]] autorelease];
But, I want to replace all titles in my navigationBar for this view, and it seems ugly to repeat this everywhere. So I did this on the delegate (after linking all the Outlet stuff)
self.tabOneNavController.navigationBar.topItem.titleView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mylogo.png"]] autorelease];
Again, it worked! ok, I'm almost getting there.
But the point is, I've 5 tabs and all of them have navigationControllers inside. I reduced the code repetition from every internal view to only 5 times, but it still. It requires that I do that for the NavController of each tab.
Then I tried to extend the UINavigationBar to create my own, where I could set this in the initializer, and use it in the interface builder as the object class. But it doesn't seem to work. Here is what I did:
#implementation MyNavigationBar
- (id)init {
self = [super self];
self.tintColor = [UIColor greenColor];
self.topItem.title = #"testing please work";
return self;
}
#end
in the interface file MyNavigationBar inherits from UINavigationBar. But this didn't work. Should I overwrite other method? which one? is this a good practice?
I'm not even sure if I should add one navigationBar for each tab, as I said, I have tabs and I want to have a navigation bar / navigate inside them. By now, after a near death experience trying to figure out how the interface builder / outlets and classes work, the code is working, I just would like to make unglify it.
Thank you!
The problem of repeating code which you describe has an elegant solution. Objective-C supports something called a "category", which allows you to add methods to a class. A common use for this is to customize navigation and tab bars. In Xcode 4, you would do something like this to add a category on UINavigationBar:
Hit Command+N or open the "New File" dialog. Next, choose "Objective-C category" from the Cocoa Touch menu:
Click Next and you will be prompted to enter the name of the class that you would like to add methods to as a category. It should look something like this:
Then, you should end up with a save file dialog. A quick note about convention here. Convention is to name a category after the original class, the plus sign, and then a description of what you're adding. Here's what yours might look like:
Once you save your file, you will need get something like this:
Look at that beauty. You can now override the default drawing/init methods as well as extend the functionality of the navbar.
I'd suggest looking into the init and drawRect methods, although I don't remember which ones people use. Also, please note that while under NDA, this may change in iOS 5, so just be prepared for that possibility.
Why not define a UIViewController subclass which sets the title view via self.navigationItem.titleView and have your other view controllers extend from that class? Then you're sharing that behavior across all of your controllers without repeating the implementation.
Basically, I cannot figure out how to change the background image. I have searched and searched and just cannot seem to find it. Anyone have any ideas? Thanks!
Update
Here is the code I use to show the View:
SettingsViewController *settingsView = [[SettingsViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:settingsView animated:YES];
If anyone needs anything else to help out I'll do my best! Thanks!
Passing a messages between different views can be done by direct call of the methods (not a good architectural solution but maybe not critical for a small projects) or with an event driven model as described in an answer above.
As for binding of a collection of objects and processing the afterward I recommend to review IBOutletCollection keyword that allows to bind multiple objects fro an InterfaceBuilder to a property with a type like NSArray.
Property declaration will look like following:
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *buttons;
The code to change the background for all the buttons will look like following:
UIImage *backgroundImage = [UIImage imageNamed:#"background.png"];
for(UIButton *button in buttons) {
[button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
}
You use setBackgroundImage:forState: to set the image.
Regarding the different views part, it depends on how you wrote your code. If the view with the buttons is controlled by the different view (by creating an instance and using addSubview:) then you can call it directly by using instanceName.buttonName (as long as you declare it as a property -thanks fichek).
If you don't manually add the view, instead through IB, you can have the button that controls the other button's image point to the IBAction in that class.
If neither of those options work you can always use NSNotificationCenter.
So Interface Builder does things to save time but what if I want to do without it ? In C# all code generated is clear and understandable, in interface builder this is hidden so I'd like at least during learning phase do things from scratch: any sample code to do so ?
Seems Apple makes things very hard so as you cannot easily use alternative to Xcode :)
http://cocoawithlove.com/2009/02/interprocess-communication-snooping.html
Yes, you can build a view without IB. Just allocate and initialize a view or a control and set its properties, e.g.:
UITextField *tf= [[UITextField alloc] initWithFrame: CGRectMake(24.5, 65, 270, 30)];
tf.delegate = self;
tf.textAlignment = UITextAlignmentCenter;
tf.autocorrectionType = UITextAutocorrectionTypeNo;
tf.autocapitalizationType = UITextAutocapitalizationTypeNone;
[self.view addSubview: tf];
But IB does not hide any generated code from you because it doesn't generate any code at all. Instead, it creates object instances and serializes them into a XIB or NIB file.
Interface Builder doesn't work in the same way as Visual Studio. It doesn't generate code, instead it generates "raw" object instances. In this sense it's not possible to see the code because there is no code generated.
One option nib2objc to convert your interfaces to code, though I'm not sure how readable that would be. As noted above, this is not the code that would be executed by your iPhone.
This blog post shows you how to get started with a nibless iPhone project.
And you might want to look at this SO question to learn about creating views (e.g. a UIButton in this case) programmatically.
Interface builder doesn't generate code to build a UI object. It creates a compressed xib data object which the iOS runtime "uncompresses" (does some housecleaning) into your pre-built object.
The paradigm is to actually think of you objects as objects in their own right, and not just the results of code execution. e.g. what you would end up with if you could "Make it so." without writing any code.