IOS response button click in another viewController - ios

Here is the main idea
+---MyViewController.m----+ +---BtnOnClickResp.m-----+
| | EventTouchUpInside: | |
| Button ---------------------------------------> OnBtnClick() |
| | textView.text=#"blabla"| | |
| *textView <------------------------------------------ + |
| | | |
+-------------------------+ +------------------------+
I want to test if button OnClick could be pressed in another controller like this:
MyViewController.h
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController
#property (nonatomic, strong) UITextView *textView;
+(id) sharedInstance;
#end
MyViewController.m
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
BtnOnClickResp.h
#import <UIKit/UIKit.h>
#interface BtnOnClickResp : UIViewController
#end
BtnOnClickResp.m
#import "BtnOnClickResp.h"
#import "MyViewController.h"
#interface BtnOnClickResp ()
#end
#implementation BtnOnClickResp
- (void) onBtnClick: (UIButton *) btn{
NSLog(#"btn was click but I am in another controller");
MyViewController *control = [MyViewController sharedInstance];
control.textView.text = #" I am setting this content in another view cheers!!!";
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The main idea is draw/add a button view in the MyViewController and make the response to click code in another controller, I thought the action assignment code:
[btn addTarget:self action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
if we change the self to the actually controller we want to use then the click event will be dispatched to that controller
But it seems not working.
Really a beginner of ios development would be happy if you don't downvote this beginner's question.
EIDT
After taking the advice as #Mike suggested,
I change the MyViewController.m to this:
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController (){
//here is the change , I made a private ref of the controller
BtnOnClickResp *respContl;
}
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:respContl action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
respContl = [[BtnOnClickResp alloc] init];
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
Now I could see the NSLog of btn was click but I am in another controller but the view content still kept not changed to #" I am setting this content in another view cheers!!!" as it expected to be in BtnOnClickResp.m
This is the launch code in AppDelagate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *control = [[MyViewController alloc] init];
[self.window setRootViewController:control];
[self.window setBackgroundColor:[UIColor greenColor]];
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}

You are adding Target
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
to
[BtnOnClickResp alloc] init]
is Wrong
Because it will create new instance and add listener to it.
However you are try to access action in other instance
You have 4 solutions
Create shared instance of BtnOnClickResp and assign target to it
Pass the self of BtnOnClickResp to the MyViewController on and assign it
Create Delegate
Post Notification

Declare a property of BtnOnClickResp and set it as button target.
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#property(nonatomic, strong) BtnOnClickResp onClickRespObj;
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (id)init{
if(self = [super init]){
self.onClickRespObj = [[BtnOnClickResp alloc] init];
}
return self;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self.onClickRespObj action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end

Related

modal UIWebView and camera/image picker issue

I need to upload a local picture in my webview (IOS).
Apparently, it seems that Apple has some problems with that.
2016-04-06 18:47:37.337 DemoWebView[839:112324] Warning: Attempt to
present on whose view is not in the window hierarchy!
(iOS 8 SDK: modal UIWebView and camera/image picker)
Despite my extensive research, I didn't find a solution to my problem.
if anyone can help me .. I would be very grateful.
class : ViewController
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setFrame:CGRectMake(80, 150, 160, 60)];
button.backgroundColor = [UIColor whiteColor];
[button setTitle:#"Click Here !" forState:UIControlStateNormal];
[self.view addSubview:button];
}
-(void) buttonClicked:(UIButton*)sender{
ViewController2 * test = [[ViewController2 alloc]init];
[self presentViewController:test animated:true completion:NULL];
}
#end
class : ViewController2
#interface ViewController2 : UIViewController
#end
#import "ViewController2.h"
#interface ViewController2 ()
#property (strong, nonatomic) UIWebView *webView;
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
_webView = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.view = _webView;
[_webView loadHTMLString:#"<br /><br /><input type=\"file\" accept=\"image/*;capture=camera\">" baseURL:nil];
}
#end
DemoProjet :
Thks
You are trying to present UIWebview indirectly from first ViewController,that's reason you are getting warning message.
Try This:
#import "ViewController2.h"
#interface ViewController2 (){
UIWebView *webView;
}
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
webView = [[UIWebView alloc] init];
[self.view addSubview:webView]
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
webView.frame = [UIScreen mainScreen].bounds;
[_webView loadHTMLString:#"Your_html_string" baseURL:nil];
}
}
#end
update: I saw your question containing link and i found that you didn't override this method
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
if ( self.presentedViewController)
{
[super dismissViewControllerAnimated:flag completion:completion];
}
}
It works with the override. Thanks a lot for your answer.
EDIT
I understand why it didn't work in the first time i tried.. In my main app, i have a UINavigationController class but i continued to override the dismiss method in my UIViewController class.

Why isn't my method call working from a different class?

I am a new programmer, and know the basics of IOS and Objective C Programming, but have run into a bug.
All I am trying to do is when a button is clicked, it calls a method from another class.
The Method I am trying to call is: [phoneCompany printPrompt];
So here is my code:
First Class: (ViewController)
.m
#import "ViewController.h"
#import "PhoneCompany.h"
#implementation ViewController
#synthesize dialTextField;
#synthesize dialButton;
#synthesize textFromCall;
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.dialTextField = [[UITextField alloc]initWithFrame:CGRectMake(83, 101, 154, 30)];
self.dialTextField.borderStyle = UITextBorderStyleRoundedRect;
self.dialTextField.placeholder = #"Dial Number";
self.dialTextField.textAlignment = NSTextAlignmentCenter;
self.dialTextField.adjustsFontSizeToFitWidth = YES;
self.dialTextField.minimumFontSize = 20;
self.dialTextField.autocorrectionType = NO;
self.dialTextField.returnKeyType = UIReturnKeyDone;
self.dialTextField.backgroundColor = [UIColor lightGrayColor];
self.dialTextField.delegate = self;
[self.view addSubview:self.dialTextField];
self.dialButton= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.dialButton setTitle:#"Dial!" forState:UIControlStateNormal];
self.dialButton.titleLabel.font = [UIFont systemFontOfSize:20];
[self.dialButton setBackgroundColor:[UIColor blueColor]];
[self.dialButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.dialButton addTarget:self action:#selector(mainCall) forControlEvents:UIControlEventTouchUpInside];
self.dialButton.frame =CGRectMake(92, 400, 125, 30);
[self.view addSubview:self.dialButton];
self.textFromCall = [[UILabel alloc]initWithFrame:CGRectMake(48,155,220,240)];
[self.textFromCall setText:#"Hello, what number would you like to call?"];
self.textFromCall.numberOfLines = 0;
self.textFromCall.lineBreakMode = UILineBreakModeWordWrap;
self.textFromCall.adjustsFontSizeToFitWidth = YES;
[self.textFromCall setTextAlignment:NSTextAlignmentCenter];
[self.textFromCall setTextColor:[UIColor blackColor]];
[self.textFromCall setBackgroundColor:[UIColor clearColor]];
[self.view addSubview: self.textFromCall];
}
-(void) mainCall{
if([self.dialTextField.text isEqualToString:#"1234567"]){
self.dialButton.enabled = NO;
self.dialTextField.enabled = NO;
PhoneCompany *phoneCompany = [[PhoneCompany alloc]init];
[NSTimer scheduledTimerWithTimeInterval: 3 target:phoneCompany selector:#selector(printPrompt)
userInfo:nil repeats:NO];
self.textFromCall.text = #"Dialing...";
[NSTimer scheduledTimerWithTimeInterval: 1 target:self selector:#selector(connectingStatement)
userInfo:nil repeats:NO];
}
else if([self.dialTextField.text isEqualToString: nil]){
self.textFromCall.text = #"Please enter a phone number.";
}
else{
self.textFromCall.text = #"Invalid Phone number.";
}
}
-(void)connectingStatement{
self.textFromCall.text = #"Connecting...";
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic) UITextField *dialTextField;
#property (weak,nonatomic) UIButton *dialButton;
#property (strong,nonatomic) UILabel *textFromCall;
-(void) mainCall;
-(void) connectingStatement;
-(void) setString:(NSString *)string;
#end
Now here is the Second Class: (PhoneCompany)
.h
#import <Foundation/Foundation.h>
#interface PhoneCompany : NSObject
-(void) printPrompt;
#end
.m
#import "PhoneCompany.h"
#import "ViewController.h"
#implementation PhoneCompany
-(void) printPrompt{
ViewController *mainView = [[ViewController alloc]init];
mainView.dialTextField.text = #"Test";
}
#end
Your call to printPrompt is fine. The problem is that you are creating a new ViewContoller in the function. The one you created in printPrompt is not the same one where you call that function. I means setString: won't replace the text of textFromCall textfield. Somehow you need to pass ViewController to PhoneCompany as a delegate and call the setString: from it.
Edited:
Try this -
In PhoneCompany.h
#class PhoneCompany;
#protocol PhoneCompanyDelegate <NSObject>
-(void)phoneCompany:(PhoneCompany *)phoneCompay
setString:(NSString *)string;
#end
#interface PhoneCompany : NSObject
#property (nonatomic, assign)id<PhoneCompanyDelegate>delegate;
- (id)initWithDelegate:(id<PhoneCompanyDelegate>)delegate;
- (void) printPrompt;
#end
In PhoneCompay.m
#implementation PhoneCompany
- (id)initWithDelegate:(id<PhoneCompanyDelegate>)delegate
{
self = [super init];
if (self)
{
self.delegate = delegate;
}
return self;
}
-(void) printPrompt
{
if (self.delegate && [self.delegate respondsToSelector:#selector(phoneCompany:setString:)])
{
[self.delegate phoneCompany:self
setString:#"Test"];
}
}
#end
When you create the PhonCompany Object in prinPrompt
PhoneCompany *phoneCompay = [[PhoneCompany alloc] initWithDelegate:self];
In your ViewController.h
#import "PhoneCompany"
#interface ViewController:UIViewController<PhoneCompanyDelegate>
It turns out, all I had to do was declare the textFromCall as a static UILabel *textFromCall, and then declare a method to edit the text. Thanks for all your answers!

Adding addTarget: method to custom UIView

I created a custom UIView something like UIStepper, because I don't like the appearance of the UIStepper. I want UIStepper have a personal count label so I added it to my custom view and created a method to increase-decrease it. Now I need a [customView addTarget:(id) action:(del) forControlEvents:(UIControlEvents)] method to catch UIControlEventValueChanged; but I couldn't find anything about implementing it. I dig around the UIButton.h, UIStepper.h files but no luck too.. Can anyone help me to do that?
Here is how I created the custom view...
CounterView.h
#import <UIKit/UIKit.h>
#interface CounterView : UIView
#property NSString* name;
#property NSInteger count;
#property UILabel *label;
#property NSInteger customTag;
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag;
#end
CounterView.m
#implementation CounterView
- (id)initWithX:(CGFloat)xPoint WithY:(CGFloat)yPoint WithName:(NSString*)newName withCount:(NSInteger)newCount withCustomTag:(NSInteger)newTag
{
self = [super initWithFrame:CGRectMake(xPoint, yPoint, 24, 52)];
if (self) {
self.customTag = newTag;
self.count = newCount;
self.name = newName;
UIButton *btnUp = [[UIButton alloc] initWithFrame:CGRectMake(3, 2, 18, 12)];
[btnUp setImage:[UIImage imageNamed:#"top.png"] forState:UIControlStateNormal];
[btnUp addTarget:self action:#selector(increaseValue) forControlEvents:UIControlEventTouchUpInside];
UIButton *btnDown = [[UIButton alloc] initWithFrame:CGRectMake(3, 38, 18, 12)];
[btnDown setImage:[UIImage imageNamed:#"bottom.png"] forState:UIControlStateNormal];
[btnDown addTarget:self action:#selector(decreaseValue) forControlEvents:UIControlEventTouchUpInside];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 14, 24, 24)];
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
self.label.textAlignment = NSTextAlignmentCenter;
[self addSubview:btnUp];
[self addSubview:btnDown];
[self addSubview:self.label];
}
return self;
}
-(void) increaseValue{
self.count++;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
-(void) decreaseValue{
self.count--;
[self.label setText:[NSString stringWithFormat:#"%ld", (long)self.count]];
}
#end
in the ViewController where you instantiate your CounterView you add this
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[yourViewInstantiation addGestureRecognizer:singleFingerTap];
[singleFingerTap release];
and the you implement the call back method:
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
//Do stuff here...
}
i hope that help you !
Just allow the actions to be set from outside of your control. Here is how to do it:
#interface CounterView : UIView
...
#property(nonatomic, strong) UIButton *btnUp;
#property(nonatomic, strong) UIButton *btnDown;
- (void)addUpTarget:(id)target action:(SEL)action;
- (void)addDownTarget:(id)target action:(SEL)action;
#end
#implementation CounterView
...
- (void)addUpTarget:(id)target action:(SEL)action
{
[_btnUp addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
}
- (void)addDownTarget:(id)target action:(SEL)action
{
[_btnDonw addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
}
...
#end
Then use methods:
- (void)addUpTarget:(id)target action:(SEL)action;
- (void)addDonwTarget:(id)target action:(SEL)action;
to set a target and actions for increasing and decreasing the values.

Programmatically navigate pages in UIPageViewController

I'm trying to implement an questionnaire app.
I have an UIPageViewController attached to the main view controller called QuizPageViewController.m. other controllers such as buttons are placed in content view controller called QuizContentViewController.m.
Now my question is how do I navigate pages of UIPageViewController programmatically from QuizContentViewController.m (eg. when buttonDoneClicked clicked)? I'm already aware of the fact that i can programmatically navigate pages using following command but my problem is I don't have access to its arguments from content view controller (QuizContentViewController).
setViewControllers:direction:animated:completion:.
following is my code.
QuizPageViewController.h
#import <UIKit/UIKit.h>
#import "QuizContentViewController.h"
#class QuizPageViewController;
#protocol QuizPageViewControllerDelegate <NSObject>
#optional // Delegate protocols
- (void)dismissReaderViewController:(QuizPageViewController *)viewController;
#end
#interface QuizPageViewController : UIViewController <UIPageViewControllerDataSource, QuizContentViewControllerDelegate>{
}
- (void)moveForward:(id)sender;
- (void)moveBackwards:(id)sender;
- (void)abort:(id)sender;
#property (nonatomic, unsafe_unretained, readwrite) id <QuizPageViewControllerDelegate> delegate;
#property (nonatomic, strong) UIPageViewController *pageView;
#end
QuizPageViewController.m
#import "QuizPageViewController.h"
#interface QuizPageViewController ()
#end
#implementation QuizPageViewController
#synthesize pageView, delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[self QuestionDet];
[super viewDidLoad];
// Do any additional setup after loading the view.
NSDictionary *option = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin] forKey:UIPageViewControllerOptionSpineLocationKey];
pageView = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:option];
[pageView setDataSource:self];
QuizContentViewController *initialVC = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialVC];
[pageView setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
CGRect viewRect = self.view.bounds;
[[pageView view] setFrame:viewRect];
[self addChildViewController:self.pageView];
[self.view addSubview:[pageView view]];
[pageView didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger) indexOfViewController:(QuizContentViewController *)viewController{
return viewController.dataObjquizNo;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
int index = [self indexOfViewController:(QuizContentViewController *)viewController];
if (index == 0 || index == NSNotFound) {
return nil;
}
index --;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
int index = [self indexOfViewController:(QuizContentViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
return [self viewControllerAtIndex:index];
}
- (QuizContentViewController *)viewControllerAtIndex:(NSInteger)index{
if (index > [quizdet count] - 1) {
return nil;
}
QuizContentViewController *cVC = [[QuizContentViewController alloc] init];
cVc.delegate = self;
Questions *quizz = [quizdet objectAtIndex:index];
[cVC setDataObjQuiz:[quizz quiz]];
[cVC setDataObjAns1:[quizz answer1]];
[cVC setDataObjAns2:[quizz answer2]];
[cVC setDataObjAns3:[quizz answer3]];
[cVC setDataObjAns4:[quizz answer4]];
[cVC setDataObjquizNo:index];
[cVC setDataObjtotalNoOfQuiz:[quizdet count]];
return cVC;
}
- (void)moveForward:(id)sender{
// Navigation forward code should goes here...
}
- (void)moveBackwards:(id)sender{
// Navigation backwards code should goes here...
}
- (void)abort:(id)sender{
[delegate dismissReaderViewController:self];
}
}
QuizContentViewController.h
#import <UIKit/UIKit.h>
#class QuizContentViewController;
#protocol QuizContentViewControllerDelegate <NSObject>
- (void)moveForward:(id)sender;
- (void)moveBackwards:(id)sender;
- (void)abort:(id)sender;
#end
#interface QuizContentViewController : UIViewController{
UITextView *txtVwQuiz;
UILabel *lblSummery;
NSString *dataObjQuiz;
NSString *dataObjAns1;
NSString *dataObjAns2;
NSString *dataObjAns3;
NSString *dataObjAns4;
NSInteger dataObjquizNo;
NSInteger dataObjtotalNoOfQuiz;
}
#property(nonatomic, unsafe_unretained, readwrite) id <QuizContentViewControllerDelegate> delegate;
#property (nonatomic, strong) NSString *dataObjQuiz;
#property (nonatomic, strong) NSString *dataObjAns1;
#property (nonatomic, strong) NSString *dataObjAns2;
#property (nonatomic, strong) NSString *dataObjAns3;
#property (nonatomic, strong) NSString *dataObjAns4;
#property NSInteger dataObjquizNo;
#property NSInteger dataObjtotalNoOfQuiz;
#end
QuizContentViewController.m
#import "QuizContentViewController.h
#import <QuartzCore/QuartzCore.h>
#define isPhone568 ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568)
#define iPhone568ImageNamed(image) (isPhone568 ? [NSString stringWithFormat:#"%#-568h.%#", [image stringByDeletingPathExtension], [image pathExtension]] : image)
#define iPhone568Image(image) ([UIImage imageNamed:iPhone568ImageNamed(image)])
# define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone
#interface QuizContentViewController ()
#end
#implementation QuizContentViewController
#synthesize dataObjQuiz, dataObjAns1, dataObjAns2, dataObjAns3, dataObjAns4, dataObjquizNo, dataObjtotalNoOfQuiz, delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor]; // Transparent
UIImageView *backgroundImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:iPhone568ImageNamed(#"QuizPage.png")]];
[self.view addSubview:backgroundImage];
[self.view sendSubviewToBack:backgroundImage];
// Do any additional setup after loading the view.
// Override point for customization after application launch
CGSize viewSize = self.view.bounds.size;
float boader;
float heightofSubVw;
boader = IS_IPAD?15:37;
heightofSubVw = viewSize.height/10;
lblSummery = [[UILabel alloc] initWithFrame:CGRectMake(boader, 5, viewSize.width-(2*boader), heightofSubVw*1)];
[lblSummery setBackgroundColor:[UIColor clearColor]];
[lblSummery setTextAlignment:UITextAlignmentLeft];
[lblSummery setFont:[UIFont systemFontOfSize:IS_IPAD?14.f:28.f]];
[lblSummery setText:[NSString stringWithFormat:#" Question %d out of %d.",dataObjquizNo+1, dataObjtotalNoOfQuiz]];
[lblSummery setTextColor:[UIColor orangeColor]];
[self.view addSubview:lblSummery];
txtVwQuiz = [[UITextView alloc] initWithFrame:CGRectMake(boader, heightofSubVw, viewSize.width-(2*boader), heightofSubVw*4)];
[txtVwQuiz setText:dataObjQuiz];
[txtVwQuiz setBackgroundColor:[UIColor clearColor]];
[txtVwQuiz setTextAlignment:UITextAlignmentLeft];
[txtVwQuiz setTextColor:[UIColor whiteColor]];
[txtVwQuiz setFont:[UIFont systemFontOfSize:IS_IPAD?15.f:30.f]];
[txtVwQuiz setEditable:NO];
[self.view addSubview:txtVwQuiz];
NSArray *options =[[NSArray alloc]
initWithObjects:dataObjAns1,dataObjAns2,dataObjAns3,dataObjAns4,nil];
MIRadioButtonGroup *group =[[MIRadioButtonGroup alloc]
initWithFrame:CGRectMake(boader, heightofSubVw*4, viewSize.width-(2*boader), heightofSubVw*5)
andOptions:options andColumns:1];
[self.view addSubview:group];
UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(boader+(IS_IPAD?6:12), heightofSubVw*8.5, IS_IPAD?44:88, IS_IPAD?44:88)];
[btnBack addTarget:self action:
#selector(navButtonBackClicked:)
forControlEvents:UIControlEventTouchUpInside];
btnBack.contentHorizontalAlignment =
UIControlContentHorizontalAlignmentCenter;
[btnBack setBackgroundImage:[UIImage imageNamed:
#"Navigation_Back.png"] forState:UIControlStateNormal];
[self.view addSubview:btnBack];
UIButton *btnDone = [[UIButton alloc] initWithFrame:CGRectMake(viewSize.width - (boader+(IS_IPAD?10 + 44 :20 + 88)), heightofSubVw*8.5, IS_IPAD?44:88, IS_IPAD?44:88)];
[btnDone addTarget:self action:
#selector(navButtonDoneClicked:)
forControlEvents:UIControlEventTouchUpInside];
btnDone.contentHorizontalAlignment =
UIControlContentHorizontalAlignmentCenter;
[btnDone setBackgroundImage:[UIImage imageNamed:
#"Navigation_Done.png"] forState:UIControlStateNormal];
[self.view addSubview:btnDone];
UIButton *btnAbort = [[UIButton alloc] initWithFrame:CGRectMake(viewSize.width - (boader+(IS_IPAD?2*10 + 88:2*20 + 176)), heightofSubVw*8.5, IS_IPAD?44:88, IS_IPAD?44:88)];
[btnAbort addTarget:self action:
#selector(navButtonAbortClicked:)
forControlEvents:UIControlEventTouchUpInside];
btnAbort.contentHorizontalAlignment =
UIControlContentHorizontalAlignmentCenter;
[btnAbort setBackgroundImage:[UIImage imageNamed:
#"Navigation_Abort.png"] forState:UIControlStateNormal];
[self.view addSubview:btnAbort];
}
-(IBAction) navButtonDoneClicked:(UIButton *) sender{
id index;
index = [NSNumber numberWithInt:dataObjquizNo];
if ([delegate respondsToSelector:#selector(moveForward:)]) {
[delegate moveForward:index];
}
}
-(IBAction) navButtonAbortClicked:(UIButton *) sender{
id index;
index = [NSNumber numberWithInt:dataObjquizNo];
if ([self.delegate respondsToSelector:#selector(abort:)]) {
[self.delegate abort:index];
}
}
-(IBAction) navButtonBackClicked:(UIButton *) sender{
id index;
index = [NSNumber numberWithInt:dataObjquizNo];
if ([delegate respondsToSelector:#selector(moveBackwards:)]) {
[delegate moveBackwards:index];
}
}
If I understand your question correctly, the QuizContentViewController's view has buttons that are pressed and once pressed it needs to notify your mainviewcontroller so it can set the view appropriately on QuizPageViewController? If this is the case, protocols are a great way for viewcontrollers to send messages to other viewcontrollers. Here is apple documentation about protocols: Working with Protocols.
Protocols are a little tricky the first time you use them. Once everything is set-up correctly you should be able to do something like this:
-(void)buttonBackClicked:(id)sender
{
[self.delegate shouldMoveBack];
}

Tapping UIButton that's a subview of UIView

I'm having trouble capturing taps on a UIButton that's a subview of a UIView. Here's how my code is setup:
// in MyClass.m
#interface MyClass ()
#property (nonatomic, retain) UIButton *myButton;
#end
#implementation MyClass
#synthesize myButton;
- (void) buttonTapped:(id) sender {
NSLog(#"button tapped!");
}
- (id) initWithFrame:(CGRect)frame {
if (!(self = [super initWithFrame:CGRectZero]))
return nil;
myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setImage:[UIImage imageNamed:#"image.png"]
forState:UIControlStateNormal];
[myButton addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
myButton.exclusiveTouch = YES;
myButton.frame = CGRectMake(100, 100, 100, 100);
[self addSubview:myButton];
return self;
}
- (void) dealloc {
[myButton release];
[super dealloc];
}
#end
The button appears in the view. The button color changes momentarily when I tap it. However the selector buttonTapped: is never called. Any idea why?
How can I verify that buttonTapped: is indeed a target of myButton?
You could verify that your current class is a target by logging the r
NSLog(#"actions for target %#",[myButton actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]);
However, I added your code to a test project (single view template) and the buttonTapped: method worked.
- (void) buttonTapped:(id) sender {
NSLog(#"button tapped!");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
UIButton * myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setImage:[UIImage imageNamed:#"image.png"]
forState:UIControlStateNormal];
[myButton addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
myButton.exclusiveTouch = YES;
myButton.frame = CGRectMake(100, 100, 100, 100);
[rv.view addSubview:myButton];
return YES;
}
The issue is somewhere else. Is the code posted the whole .h and .m for MyClass?

Resources