UIButton in Objective - c (programmatically) - objective-c

hy,
I'm new in objective-c. I'm trying to add a button into my UIView. But I can't see the button in my application. I tried a lot but nothing worked.
I know there are many posts about that but no solution worked at my code.
PinViewController.m:
#import "PinViewController.h"
#implementation PinViewController
#synthesize view,one;
-(instancetype)init{
self = [super init];
if(self){
view = [[UIView alloc] init];
}
return self;
}
-(void)viewDidLoad{
UIButton *btnname = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnname setTitle:#"Click Me" forState:UIControlStateNormal];
btnname.frame = CGRectMake(28, 31, 42, 21);
[self.view addSubview:btnname];
}
PinViewController.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface PinViewController : UIViewController
#property(nonatomic, retain) UIView *view;
#property UIButton *one;
#end
In appdeligate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.rootViewController = [[PinViewController alloc]init];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Thank you for your help :)

I take from your question that you specifically want to not have storyboards or xibs. That's a perfectly legitimate but somewhat infrequent choice, and it has it's pros and cons.
You are writing a wrong constructor for PinViewController, which should be a subclass of UIViewController, but it class UIView's constructor instead (which is not its parent).
The other thing is that you shouldn't create (and synthesise) a new property 'view', it is already there for UIViewController, and this way the default setters/getters will be overridden. And you create your new view by setting the property. You'll also have to specify frame otherwise it will have no size. So it is:
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
Third problem is that viewDidLoad was never called. According to documentation at Apple
This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method.
This does not happen since you don't create the view in the loadView method. The loadView method, in turn, is not called at all, because you create the view in the constructor. So the solution is to not override the constructor at all, but do instead:
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
(Alternatively, you can just call viewDidLoad manually from the constructor after creating the view, which is less nice but does the job)

Related

UIGestureRecognizer hooked up to UIVIew

I'm a noob to iOS development (so please bear with me on this), and I'm trying to create a simple touch application with Xcode from scratch. I have spent a week on this, but I couldn't seem to find out what I have been missing so here I am, asking for some guidance :)
First, I created an empty application, then created a xib file (MainWindow.xib) and added a window object (Main_Window) to it. Then, I created a View object (Main_View) within this Main_Window, and added a label object (lblTitle) to this view. The Main_View object pretty much covered the entire Main_Window screen.
So, in short, the hierarchy of my MainWindow.xib is like this: Main_Window --> Main_View --> lblTitle.
Finally, I created a ViewController object (Main_View_Controller) with its "view" set to Main_View and its "rootViewController" set to "Main_Window".
In the project,
I subclassed UIView with "TouchEvent_View", hooked up to "Main_View" in the xib file.
I subclassed UIViewController with "TouchEvent_ViewController", hooked up to "Main_View_Controller" in the xib file.
In my AppDelegate.h,
I created an "IBOutlet UIWindow *window", hooked up to "Main_Window" in the xib file.
I created an object for my viewController and view classes.
#property (strong, nonatomic) IBOutlet UIWindow *window;
#property (strong, nonatomic) TouchEvent_ViewController * myViewController;
#property (strong, nonatomic) TouchEvent_View *myView;
In AppDelegate.m, I hooked up "MainWindow.xib" with myViewController:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.backgroundColor = [UIColor whiteColor];
self.myViewController = [[[TouchEvent_ViewController alloc]
initWithNibName:#"MainWindow" bundle:nil] autorelease];
[self.window makeKeyAndVisible];
return YES;
}
In "Touch_Event_ViewController.m", I coded the viewDidLoad message as followed:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Hi! ViewController's viewDidLoad msg sent!");
TouchEvent_View * mView = [[TouchEvent_View alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
mView.backgroundColor = [UIColor blueColor];
[self.view addSubview:mView];
[mView release];
}
In "TouchEvent_View.m", I instantiated a UITapGestureRecognizer object and hooked it up to a handler method as followed:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(#"[TouchEvent_View initWithFrame] sent!");
// Initialization code
//-----------------------
//Touch event declaration
//Single tap
UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(SingleTap_Handler)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
//singleTap.delegate = self;
[self addGestureRecognizer:singleTap];
}
return self;
}
-(void) SingleTap_Handler :(UITapGestureRecognizer *)GR
{
NSLog(#"Hi! You just touched the screen!");
}
When I compiled and deployed the project into my iPad3, every thing worked just as planned until the Touch event, which didn't work.
I got the following messages printed out to the console window:
2012-08-26 14:03:59.589 Ex_TouchEvents_01[806:707] Hi! ViewController's viewDidLoad msg sent!
2012-08-26 14:03:59.593 Ex_TouchEvents_01[806:707] [TouchEvent_View initWithFram] sent!
But I did not see the "Hi, you just touched the screen!" message after I touched the screen. In addition, I didn't see the background of the View area set to blue either. So, I must have been missing something that was very simple. I have been googling all over the web, but I couldn't figure out what I missed. Would some body kindly point out what I have done wrong?
I don't have access to my Mac to test this, but I believe you're missing a colon in this line.
UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(SingleTap_Handler)];
It needs to be:
UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(SingleTap_Handler:)];
If a method takes any parameters, the colon(s) are part of the selector.
Erm, can you try putting:
self.userinteractionEnabled = YES;
in your init method?
UIViews by default is set to not respond to touch events so you have to enabled them first before your tap gestures work.

How can i close UIView

I'm new to iOS and Objective-C. I have an application that displays a table view, and opens a new view when click the user clicks on a row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[detailController changeSubjectText:[subject_data_Array objectAtIndex:indexPath.row]];
//navigationController = [[UINavigationController alloc] initWithRootViewController:detailController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
}
In my detail view I have coded:
-(IBAction)closeDetail:(id)sender {
NSLog(#"closeDetail");
[self.view removeFromSuperview];
}
But it's not working. Can anyone help?
Can anyone help me?
how i can close view?
download my code in --> http://www.vasuta.com/ios/multiview2.zip
open build and run click one row in "Bulletin Board" DetailView it's open click Close …..
why DetailView is not full screen and why can't close detail view?
i open it wrong or i close it wrong
help me please
didSelectRowAtIndexPath you can see in "GadgetBulletinsTVContoller.m" and close command you can see in "DetailViewController.m"
Thank you very much
ps. sorry for my english skill :(
Why are you creating that window object and why are you trying to add your subview to it?
if you want to add a subview you should add it to the parent, the tableview or the parent of the tableView.
a better idea would be to push a new view controller on the stack that would display the info you want to show.
Here is a tutorial that shows how to push a new view controller when selecting a cell in a tableview tutorial link .
EDIT:
in MultipleAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions should look like below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[MultipleViewController alloc] initWithNibName:#"MultipleViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
navController.navigationBarHidden = YES;
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
In GadgetBulletinsTVContoller.h declare a protocol like below:
#protocol GadgetBulletinsTVControllerDelegate <NSObject>
#optional
- (void)showItemDetails:(id)selectedItem;
#end
and a delegate property:
#property (nonatomic, assign)id<GadgetBulletinsTVControllerDelegate>delegate;
In GadgetBulletinsTVContoller.m synthesize the delegate.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
should look like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if([delegate respondsToSelector:#selector(showItemDetails:)])
{
[delegate showItemDetails:[subject_data_Array objectAtIndex:indexPath.row]];
}
}
In FirstViewController.m tell the controller to implement the GadgetBulletinsTVControllerDelegate like this:
#interface FirstViewController ()<GadgetBulletinsTVControllerDelegate>
in viewDidLoad method tell the gadgetBulletinsController that his delegate is the FirstViewController class, like this:
if (gadgetBulletinsContoller == nil) {
gadgetBulletinsContoller = [[GadgetBulletinsTVContoller alloc] init];
gadgetBulletinsContoller.delegate = self;
}
and implement the GadgetBulletinsTVControllerDelegate's methods:
- (void)showItemDetails:(id)selectedItem
{
if([delegate respondsToSelector:#selector(showDetailsScreenForItem:)])
{
[delegate showDetailsScreenForItem:selectedItem];
}
}
In FirstViewController.h declare a protocol like below:
#protocol FirstViewControllerDelegate <NSObject>
- (void)showDetailsScreenForItem:(id)item;
#end
and declare a delegate property like below(don't forget to synthesize in .m file):
#property (nonatomic, assign)IBOutlet id<FirstViewControllerDelegate>delegate;
In MultipleViewController.xib select the FirstViewController screen and in outlets drag from the delegate to the fileOwner for setting the value of the delegate to the MultipleViewController(you can do this in code if you want to).
In MultipleViewController.m tell the MultipleViewController to implement the FirstViewControllerDelegate protocol like below:
#interface MultipleViewController ()<FirstViewControllerDelegate>
and implement the protocol method:
- (void)showDetailsScreenForItem:(id)item
{
DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[detailController changeSubjectText:item];
[self.navigationController pushViewController:detailController animated:YES];
}
In DetailViewController modify the closeDetail method to look like this:
- (IBAction)closeDetail:(id)sender {
NSLog(#"closeDetail");
[self.navigationController popViewControllerAnimated:YES];
}
and voila, Your GadgetBulletinsTVController items details are pushed. You need to do the same steps for the other controllers from where you want to show details.
instead of removing the view from window just reload the basic view which contains all the table views using self.window.rootviewcontroller
EDIT
i got the solution by creating appDelegate what you have to do is just described below
First .h and .m file of AppDelegate Here (MultipleAppDelegate)
in .h add
#property (strong, nonatomic) id<UIApplicationDelegate>delegate;
in .m add
#synthesize delegate;
now where ever you like to add detailView just add below in .h and .m files as described
in .h file here(GadgetBulletinsTVContoller)
#import "MultipleAppDelegate.h"
and in interface one variable like this
MultipleAppDelegate *Mydelegate;
in .m file in viewDidLoad or loadView method
Mydelegate = [[UIApplication sharedApplication]delegate];
then at loading the detailView do this
navigationController = [[UINavigationController alloc] initWithRootViewController:detailController];
Mydelegate.window.rootViewController = navigationController;
[Mydelegate.window makeKeyAndVisible];
now at the detailViewController's .h and .m files
in .h file
#import "MultipleAppDelegate.h"
and in interface
MultipleAppDelegate *appDelegate;
in .m file in viewDidLoad or loadView method
appDelegate = [[UIApplication sharedApplication]delegate];
and on close button click
//Not required
//[self.navigationController popViewControllerAnimated:NO];
appDelegate.viewController = [[MultipleViewController alloc] initWithNibName:#"MultipleViewController" bundle:nil];
appDelegate.window.rootViewController = appDelegate.viewController;
[appDelegate.window makeKeyAndVisible];
That's all it will work fine only problem is that it take's 1 or 2 seconds to navigate and show the multipalViewController
enjoy Coding :)
Happy Coding :)

setting self of UIView background color

i'm trying to do this from inside the .m of a custom view class that is not being loaded from the XIB, but rather programmatically:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor=[UIColor redcolor];
}
return self;
}
i have the same result whether i put the background color in the initWithFrame or other methods. the background color property doesn't take. from the controller, which owns this custom view, i can set the background color fine, with:
self.mycustomview.backgroundColor=[UIColor redcolor];
But I'd like to do this from within the custom view itself, keep stuff like this independent. both the controller and the custom view import UIKit.
I also tried this, which was available from Code Sense:
self.View.backgroundColor=[UIColor redcolor];
but that doesn't work either. i tried both view and View here. I'm sure I'm overlooking something very obvious.
in the view controller i have this, and it works fine. the custom view is called "mapButtons.h":
- (void)viewDidLoad
{
CGRect frame=CGRectMake(0, 0, 320, 460);
self.mapButtons=[[mapButtons alloc] initWithFrame:frame];
self.mapButtons.backgroundColor=[UIColor redColor];
[self.view addSubview:self.mapButtons];
the .h of the custom view is this:
#import <UIKit/UIKit.h>
#interface mapButtons : UIView
If your view is getting created from a XIB (i.e. you added it to some other view using Interface Builder), -initWithFrame: is not going to get called. An object being loaded from a XIB receives -initWithCoder: instead. Try this:
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if(self)
{
self.backgroundColor = [UIColor redColor];
}
return self;
}
I have tested again and this is the full source for what I am doing that works
// MapButtons.h
#import <UIKit/UIKit.h>
// As a note you normally define class names starting with a capital letter
// but I did test this with mapButtons as you had it
#interface MapButtons : UIView
#end
// MapButtons.m
#import "mapButtons.h"
#implementation mapButtons
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor redColor];
}
return self;
}
#end
// TestAppDelegate.m
#implementation TestAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MapButtons *view = [[MapButtons alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:view];
[self.window makeKeyAndVisible];
return YES;
}
The fact that xcode is not auto completing is odd but I seem to have this issue intermittently so I have no real solution. People sometimes suggest deleting the projects derived data and restarting xcode.

Programming iOS: clarifications about Root View Controller

Through this question I would like to know if I understand well the notion of Root View Controller.
In iOS application, the Root View Controller (RVC) is the controller whose view gets added to the UIWindow application at startup, isn't true?
[window addSubview:rvcController.View];
[window makeKeyAndVisible];
Now, an UIWindow has also a rootViewController property. When running the previous snippet of code, does that property gets populated with the rvcController or do I have to set it explicitly?
Then, in a UINavigationController it is possible to set a RVC that is different from the previous RVC set for the entry point.
In this case, the first time I add a controller to the navigationController stack (pushing a new controller on it), does the framework set that controller as the RVC for the navigationController or do I have to set it explicitly through initWithRootViewController method?
Ya.. when I began iPhone dev.. the rootViewController thing threw me for a loop too. But it’s really straight forward.
when the app starts, I create a UIWindow object in my app delegate class. Also, in that class, I have a property of type UIWindow called window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIWindow *w = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window=w;
[w release];
// other code here...
}
I then create a UIViewController whose view will be the first view in the window hierarchy, this could be called the "root view controller".
The confusing part is...that often we create a UINavigationController as the "root view controller" and that navigation controller has an init method that asks for a "RootViewController", which is the first viewcontroller it will place on its stack.
So, the window gets a "root view controller", which is the UINavigationController, which also has a RootViewController, which is the first view controller you want to show.
once you sort that out, its all makes sense.. I think :-)
here is some code that does it all.. (taken from a project I have open in front of me)
//called with the app first loads and runs.. does not fire on restarts while that app was in memory
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//create the base window.. an ios thing
UIWindow *w = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window=w;
[w release];
// this is the home page from the user's perspective
//the UINavController wraps around the MainViewController, or better said, the MainViewController is the root view controller
MainViewController *vc = [[MainViewController alloc]init];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:vc];
self.navigationController=nc; // I have a property on the app delegate that references the root view controller, which is my navigation controller.
[nc release];
[vc release];
//show them
[self.window addSubview:nc.view];
[self.window makeKeyAndVisible];
return YES;
}
Now, an UIWindow has also a rootViewController property. When running the previous snippet of code, does that property gets populated with the rvcController or do I have to set it explicity?
You have to set it explicitly, and if you do, you can remove the addSubview line, because that's handled automatically when you set a root view controller.
Then, in a UINavigationController it is possible to set a RVC that is different from the previous RVC set for the entry point.
Of course, a navigation controller's root view controller has nothing to do with that of the window.
In this case, the first time I add a controller to the navigationController stack (pushing a new controller on it), does the framework set that controller as the RVC for the navigationController or do I have to set it explicity through initWithRootViewController method?
initWithRootViewController is just a shortcut for initializing an empty navigation controller and pushing the first (root) view controller onto the stack. Note that rootViewController is not a property of UINavigationController, you would access it via [navController.viewControllers objectAtIndex:0].
firstly you can create A empty project in Xcode. after you add the new file on objectivec class view controller with xiv. now you can add to this code in appdeligate.m
and set the rootviewcontroller in appdeligate
NOTE:- ViewController.h import to the appdeligate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
ViewController *viewcontroller =[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController= viewcontroller;
[self.window makeKeyAndVisible];
return YES;
}
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
ViewController *viewcontroller =[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController= viewcontroller;
[self.window makeKeyAndVisible];
return YES;
}

Push NavigationController from UIScrollView

how can I push a new view onto the stack of a NavigationController from a UIScrollView?
I tried
[self.navigationController pushViewController:myNewViewController animated:YES];
but get "navigationController not in structure or union".
regards
You don't have a navigation controller in your app. You need to create one. Something like:
In your appDelegate create a UINavigationController instance variable and then use your existing viewController as the rootViewController of the navigation controller.
e.g. in pure code using a UITableViewController (you can use xibs as well which your template app probably does).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Create root view and navigation controller
UITableViewController *rootViewController = [[[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
// Not necessary if you're using xibs
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Add the nav controller's root view to the window
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
Then you can push/pop new views in the way you're attempting.