The main view has a label and a button. I added one subview which contain a UILabel and a button. What I want to do is that I want to update two labels at the both view by pressing one of two button.
The problem is, if I click the button of the subview, the label of the subview is only updated. Conversely, the label of the main view is only changed when I click the button in the main view.
I am wondering how to update each label.text of the other view.
Thanks in advance...
Here is my code.
1. ViewController.h
#import <UIKit/UIKit.h>
#import "SubView.h"
#interface ViewController : UIViewController{
SubView *subView;
}
#property (weak, nonatomic) SubView *subView;
#property (retain, nonatomic) IBOutlet UILabel *amount;
#end
2. ViewController.m
#import "ViewController.h"
#import "SubView.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize subView=_subView;
#synthesize amount;
- (void)viewDidLoad
{
[super viewDidLoad];
subView = [[SubView alloc]initWithFrame:CGRectMake(10, 10, 300, 600)];
[self.view addSubview:subView];
amount = [[UILabel alloc]initWithFrame:CGRectMake(400, 400, 100, 50)];
amount.text = #"test in the main view";
[self.view addSubview:amount];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(400, 300, 40, 20);
btn.backgroundColor = [UIColor clearColor];
[btn addTarget:self action:#selector(labelChange:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn]; // add a button in the main view
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)labelChange:(id)sender{
amount.text = #"defaul label";
SubView *sv = [[SubView alloc]init];
sv.addObject2.text = #"label in the subview";
NSLog(#"sv.addObject2.text = %#",sv.addObject2);
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#end
3. SubView.h
#import <UIKit/UIKit.h>
#interface SubView : UIView {
UIButton *btn;
UILabel *label;
}
//#property (strong, nonatomic) UIView *view;
#property (weak, nonatomic) UIButton *btn;
#property (weak, nonatomic) UILabel *label;
- (UIButton *)addObject1;
- (UILabel *)addObject2;
#end
4. SubView.m
#import "SubView.h"
#import "ViewController.h"
#implementation SubView
#synthesize btn=_btn, label=_label;
//#synthesize view;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
//UIView *contentView = [[UIView alloc]initWithFrame:frame];
self.backgroundColor = [UIColor blackColor];
UIButton *object1 = [self addObject1];
UILabel *object2 = [self addObject2];
[self addSubview:object1];
[self addSubview:object2];
return self;
}
- (UIButton *)addObject1{
btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 100, 20);
btn.backgroundColor = [UIColor clearColor];
[btn addTarget:self action:#selector(labelChange:) forControlEvents:UIControlEventTouchUpInside];
return btn;
}
- (IBAction)labelChange:(id)sender{
label.text = #"change the label in the subview";
ViewController *vc = [[ViewController alloc]init];
[vc.amount setText:#"change the label in the mainview"];
}
- (UILabel *)addObject2{
label = [[UILabel alloc]initWithFrame:CGRectMake(10, 50, 200, 50)];
[label setText: #"default"];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:#"Arial" size:12];
label.textColor = [UIColor whiteColor];
return label;
}
#end
I think u need to read "The Objective-C Programming Language" and know how the "Object" and "Pointer" means
Here is the code
SubView.h
#import <UIKit/UIKit.h>
#interface SubView : UIView {
UIButton *btn;
UILabel *label;
}
#property (weak, nonatomic) UIViewController *vc;
#property (weak, nonatomic) UIButton *btn;
#property (weak, nonatomic) UILabel *label;
- (UIButton *)addObject1;
- (UILabel *)addObject2;
#end
Subview.m
#import "SubView.h"
#import "ViewController.h"
#implementation SubView
#synthesize btn=_btn, label=_label;
#synthesize vc;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor blackColor];
UIButton *object1 = [self addObject1];
UILabel *object2 = [self addObject2];
[self addSubview:object1];
[self addSubview:object2];
return self;
}
- (UIButton *)addObject1{
btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 100, 20);
btn.backgroundColor = [UIColor clearColor];
[btn addTarget:self action:#selector(labelChange:) forControlEvents:UIControlEventTouchUpInside];
return btn;
}
- (IBAction)labelChange:(id)sender{
label.text = #"change the label in the subview";
[vc.amount setText:#"change the label in the mainview"];
}
- (UILabel *)addObject2{
label = [[UILabel alloc]initWithFrame:CGRectMake(10, 50, 200, 50)];
[label setText: #"default"];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:#"Arial" size:12];
label.textColor = [UIColor whiteColor];
return label;
}
#end
ViewController.m
#import "ViewController.h"
#import "SubView.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize subView=_subView;
#synthesize amount;
- (void)viewDidLoad
{
[super viewDidLoad];
subView = [[SubView alloc]initWithFrame:CGRectMake(10, 10, 300, 600)];
subView.vc = self;
[self.view addSubview:subView];
amount = [[UILabel alloc]initWithFrame:CGRectMake(400, 400, 100, 50)];
amount.text = #"test in the main view";
[self.view addSubview:amount];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(400, 300, 40, 20);
btn.backgroundColor = [UIColor clearColor];
[btn addTarget:self action:#selector(labelChange:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn]; // add a button in the main view
}
- (IBAction)labelChange:(id)sender{
amount.text = #"defaul label";
subview.addObject2.text = #"label in the subview";
}
#end
I think I got what you are trying to do and here is what you should do:
1- Create 3 new files (xib,m,h) call them SubView.xib,m,h. You have to make sure it inherits UIView.
2- in the xib file draw the subview elements and hook the IBOutlets with it. But make sure that the file owner is the ViewController and the root view class type is "SubView"
3- Make an IBOutlet of type Subview in ViewController
4- open SubView.xib and hook the SubView (the root node in the objects tree) with the File Owner IBOutlet you made # step 3
to load the new SubView in the ViewController.m simply call this line:
after that line your IBOutlet in ViewController will have the object of SubView.
[[NSBundle mainBundle] loadNibNamed:#"SubView" owner:self options:nil];
in the above code self is reflected to the ViewController
Related
UIBarItem does not respond to clicks inside UIToolbar which is setup as inputAccessoryView on a UITextField.
The button does not show click animation when I try to click it, callback does not get called.
My setup looks like:
#interface MyViewController()
#property (weak, nonatomic) IBOutlet UITextField *closeDateTextField;
#property (strong, nonatomic) UIToolbar * datePickerToolbar;
#end
I setup toolbar with button:
- (void)viewDidLoad {
self.datePickerToolbar = [[UIToolbar alloc] init];
UIBarButtonItem * doneBtn =
[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(hidePicker:)];
add button to toolbar and set toolbar as inputAccessoryView of UITextField:
[self.datePickerToolbar setItems:#[doneBtn] animated:NO];
self.closeDateTextField.inputAccessoryView = self.datePickerToolbar;
}
When I click on closeDateTextField the keyboard appears with a Done button in toolbar but the button does not respond to click, the hidePicker: does not get called.
- (void)hidePicker:(id)sender {
[self.closeDateTextField resignFirstResponder];
}
Any idea what I'm doing wrong?
I just tried the following code and it worked just fine. Tested on both iOS 6 & 7 simulator.
#interface HSViewController
#property (weak, nonatomic) IBOutlet UITextField *closeDateTextField;
#property (strong, nonatomic) UIToolbar * datePickerToolbar;
#end
#implementation HSViewController
- (void)viewDidLoad
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[super viewDidLoad];
self.datePickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
UIBarButtonItem * doneBtn =
[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(hidePicker:)];
[self.datePickerToolbar setItems:#[doneBtn] animated:NO];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 120)];
textField.backgroundColor = [UIColor greenColor];
[self.view addSubview:textField];
self.closeDateTextField = textField;
self.closeDateTextField.inputAccessoryView = self.datePickerToolbar;
}
- (void)hidePicker:(id)sender {
NSLog(#"%s", __PRETTY_FUNCTION__);
[self.closeDateTextField resignFirstResponder];
}
#end
self.datePickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 43)];
It worked with me when I did the toolbar height less than 44. 43 for an example
when it was 44 it crashes
Instead of setting the UIToolbar frame you should only set its autoresizingMask:
self.datePickerToolbar.autoresizingMask =
UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
This way you'll have the expected behavior while being device/orientation independent.
I have a view which includes two subviews. I had it working so that only one subview was shown at a time and each subview had a button and when the button was clicked the subview would flip over and the next subview would appear. The problem was that it appeared as though the entire view was flipping. After reading on this site about how to solve the problem I attempted to add the subviews to a container and flip that instead. However now, although my first subview is showing up when I press the button it no longer flip. It doesn't do anything. I put a log statement in the method which flips the subviews, as well as a breakpoint and as far as I can tell it no longer gets called. I'm very new to xcode and objective c and delegates and I have no idea how to proceed. Any help would be appreciated. Thanks.
I have included the relevant code here:
The header for the ViewController
#interface ExerciseViewController : UIViewController<ExerciseSubViewDelegate>
//stuff for subviews
#property (nonatomic, strong) ExerciseSubViewImage *subViewImage;
#property (nonatomic, strong) ExerciseSubViewText *subViewText;
#property UIView *panel;
#end
This is the code for the ViewController:
#interface ExerciseViewController ()
#end
#implementation ExerciseViewController
#synthesize subViewImage, subViewText;
- (void)viewDidLoad
{
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
}
-(ExerciseSubViewImage *)subViewImage
{
if (!subViewImage)
{
CGRect subViewImageFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewImage = [[ExerciseSubViewImage alloc] initWithFrame:subViewImageFrame];
[_panel addSubview:subViewImage];
}
return subViewImage;
}
-(ExerciseSubViewText *)subViewText
{
if (!subViewText)
{
CGRect subViewTextFrame = CGRectMake(0,0, _panel.bounds.size.width, _panel.bounds.size.height);
self.subViewText = [[ExerciseSubViewText alloc] initWithFrame:subViewTextFrame];
self.subViewText.backgroundColor = [UIColor blueColor];
[_panel addSubview:subViewText];
}
return subViewText;
}
-(void)exerciseSubViewImagePressed
{
[UIView transitionWithView:_panel
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[subViewImage removeFromSuperview];
[_panel addSubview:subViewText];
}
completion: nil];
//This is how I did it before I added the container
/*[UIView transitionFromView:subViewImage
toView:subViewText
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewText.delegate = self;*/
NSLog(#"Ipushedtheimage");
}
-(void)exerciseSubViewTextPressed
{//I haven't updated this yet
[UIView transitionFromView:subViewText
toView:subViewImage
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
self.subViewImage.delegate = self;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
subViewImage = nil;
subViewText = nil;
}
#end
This is the code for the delegate
#import
#protocol ExerciseSubViewDelegate <NSObject>
-(void) exerciseSubViewImagePressed;
-(void) exerciseSubViewTextPressed;
#end
I am also added the code for the first subview:
#import
#import "ExerciseSubViewDelegate.h"
#interface ExerciseSubViewImage : UIView
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, assign) id<ExerciseSubViewDelegate>delegate;
#property (strong, nonatomic) UIImageView *exerciseImageView;
#end
#import "ExerciseSubViewImage.h"
#import "UIImage+animatedGIF.h"
#implementation ExerciseSubViewImage
#synthesize button;
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialization code
self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect buttonFrame = CGRectMake(50,200,100,35);
self.button.frame = buttonFrame;
[self.button setTitle:#"Image"forState:UIControlStateNormal];
[self.button addTarget:self
action:#selector(buttonTouched)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.button];
_exerciseImageView = [[UIImageView alloc] initWithFrame:CGRectMake(50,20,160,158)];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"AppleLogo" withExtension:#"gif"];
_exerciseImageView.image = [UIImage animatedImageWithAnimatedGIFURL:url];
[self addSubview:self.exerciseImageView];
}
return self;
}
-(void)buttonTouched
{
NSLog(#"imagebuttonpressed");
[self.delegate exerciseSubViewImagePressed];
}
Again, any help would be appreciate. I know I'm probably just not understanding something simple.
Ok. This took me all weekend but I finally figured it out on my own. I thought I would shere the answer here in case anyone else ever has a similar problem. After trying several other approaches I finally went back to the approach I used here and started inserting a whole bunch of NSLogs to determine the order that every thing was executing in. What I finally ended up doing was changing this: (all in the top ViewController)
self.subViewImage.delegate = self;
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
to this:
//create panel
_panel = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.bounds.size.width, s self.view.bounds.size.height/2)];
_panel.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_panel];
[_panel addSubview:subViewImage];
//Set the subview delegates
self.subViewImage.delegate = self;
self.subViewText.delegate = self;
I wanted to programmatically add myView to parent view. But it doesn't show up on screen. What's wrong with the code?
#interface ViewController ()
#property (nonatomic,weak) UIView *myView;
#end
#implementation ViewController
#synthesize myView = _myView;
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect viewRect = CGRectMake(10, 10, 100, 100);
self.myView = [[UIView alloc] initWithFrame:viewRect];
self.myView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.myView];
}
Replace
#property (nonatomic,weak) UIView *myView;
with
#property (strong, nonatomic) UIView *myView;
and it should work :)
#interface ViewController ()
#end
#implementation ViewController
UIView *myView;
-(void)viewDidLoad
{
[super viewDidLoad];
CGRect viewRect = CGRectMake(10, 10, 100, 100);
myView = [[UIView alloc] initWithFrame:viewRect];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
}
try this it will work…
I have a scrollview in which i am creating buttons programmatically. On touch, button is supposed to load another nib. The problem is, on touch, i am getting
[ViewController buttonTest]: unrecognized selector sent to instance
Let me take you through the code:
appdelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *viewController;
appdelegate.m
#import "ViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize viewController = _viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController *view = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.viewController = [[UINavigationController alloc] initWithRootViewController:view];
self.window.rootViewController = self.viewController;
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[self.window makeKeyAndVisible];
return YES;
}
Viewcontroller.h
#class newView;
#interface ViewController : UIViewController{
UIScrollView * scrollView;
IBOutlet UIButton *btn;
}
- (IBAction)butttonTest:(id)sender;
#property (strong, nonatomic) newView *secondView;
and finally, ViewController.m
- (void)loadView {
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
scrollView.contentSize=CGSizeMake(320,960);
UIImageView *tempImageView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.jpeg"]];
UIImage * buttonImage = [UIImage imageNamed:#"contentlist_active.png"];
self.view=scrollView;
[scrollView addSubview:tempImageView2];
scrollView.userInteractionEnabled = YES;
btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(22, 100, 277, 32);
[btn setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btn setTitle:#"hello world" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(buttonTest:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:btn];
}
To load the view, I have code:
[btn addTarget:self action:#selector(buttonTest) forControlEvents:UIControlEventTouchUpInside];
What am i doing wrong?
OH yes, here is the method for buttenPressed
- (IBAction)butttonTest:(id)sender {
self.secondView = [[newView alloc] initWithNibName:#"newView" bundle:nil];
[self.navigationController pushViewController:self.secondView animated:YES];
}
your method is called - (IBAction)butttonTest:(id)sender.
Three t and a parameter.
But your selector is #selector(buttonTest). Two t and no parameter.
The two method signatures just don't match.
change the addTarget:action:forControlEvents: call like this:
[btn addTarget:self action:#selector(butttonTest:) forControlEvents:UIControlEventTouchUpInside];
or remove the third t on both.
Have you implemented the buttonTest: method (as i dont see it in the code above)?
Try this:
[btn addTarget:self action:#selector(buttonTest:) forControlEvents:UIControlEventTouchUpInside];
Note buttonTest: rather than buttonTest.
I am a newbie in iphone developmenst its my second sample code.
I am trying to add subViews to a View and generate events according to the view which is touched. The projects I am experimenting with is a newly created, clean Window-Base application,
I wrote the following code into the one and only viewController's code:
#interface testViewController : UIViewController {
IBOutlet UIView *redView;
IBOutlet UIView *redView1;
IBOutlet UIView *blueView;
}
//---expose the outlet as a property---
#property (nonatomic, retain) IBOutlet UIView *redView;
#property (nonatomic, retain) IBOutlet UIView *redView1;
#property (nonatomic, retain) IBOutlet UIView *blueView;
//---declaring the action---
-(IBAction) viewClicked: (id) sender;
#end
And its .m file contains an action responder.what i am trying to do is when my views are touched they will generate an event which should be treated by this single method which will change the backcolor of the redview accordingly.
-(IBAction) viewClicked:(id) sender {
redView.backgroundColor = [UIColor blackColor];
}
i worte the delegate in this way
#interface testAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
testViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet testViewController *viewController;
#end
In testAppdelegate.m i am making views and subviews accoring to it and they are displaying it very well but i am unable to get any events on it when they are touched in (viewClicked:)
method.How to do this????
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor whiteColor];
// Create a simple red square
CGRect redFrame = CGRectMake(0, 10, 320, 100);
UIView *redView = [[UIView alloc] initWithFrame:redFrame];
redView.backgroundColor = [UIColor redColor];
//-------------------------------------------------------------------------------------------------------
// Create a simple blue square
CGRect blueFrame = CGRectMake(5, 115, 100, 100);
UIView *blueView = [[UIView alloc] initWithFrame:blueFrame];
blueView.backgroundColor = [UIColor blueColor];
// Create a simple blue square
CGRect blueFrame1 = CGRectMake(110, 115, 100, 100);
UIView *blueView1 = [[UIView alloc] initWithFrame:blueFrame1];
blueView1.backgroundColor = [UIColor blueColor];
// Add the square views to the window
[window addSubview:redView];
[window addSubview:blueView];
[window addSubview:blueView1];
[window addSubview:viewController.redView];
[window addSubview:viewController.blueView];
[window addSubview:viewController.blueView1];
[window makeKeyAndVisible];
}
Thanks
How are you linking viewClicked to the views? Generally, to handle touches, you use touchesBegan:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
NSUInteger numTaps = [touch tapCount];
if ([touches count] > 1)
NSLog(#"mult-touches %d", [touches count]);
if (numTaps < 2) {
} else {
NSLog(#"double tap");
}
}