How do I call this method from the button selector code I have below:
- (void)displayEditorForImage:(UIImage *)imageToEdit
{
AFPhotoEditorController *editorController = [[AFPhotoEditorController alloc] initWithImage:imageToEdit];
[editorController setDelegate:self];
[self presentViewController:editorController animated:YES completion:nil];
}
here's the UIButton I'm trying to call the method with:
//edit button
UIButton *editButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[editButton addTarget:self
action:#selector(editBtnTouch)
forControlEvents:UIControlEventTouchDown];
[editButton setTitle:#"Effects" forState:UIControlStateNormal];
**// the following line shows the selector where I'm unsure how to call the method from the code above**
if ([[UIScreen mainScreen] respondsToSelector:#selector(displayEditorForImage:)] &&
([UIScreen mainScreen].scale == 2.0)) {
// Retina display
editButton.frame = CGRectMake(220.0, 320.0, 60.0, 40.0);
} else {
editButton.frame = CGRectMake(220.0, 315.0, 60.0, 40.0);
}
[self.view addSubview:editButton];
thanks for the help
When the selector you add to the button is called, the button itself will be passed as the first argument if the selector allows for one. In order to get a reference to your image, you would either need to do this (assuming the image you want is the background image for the button):
- (void)displayEditorForImage:(UIButton*)sender {
UIImage* imageToEdit = [sender backgroundImageForState:UIControlStateNormal];
AFPhotoEditorController *editorController = [[AFPhotoEditorController alloc] initWithImage:imageToEdit];
[editorController setDelegate:self];
[self presentViewController:editorController animated:YES completion:nil];
}
Or you would need to make a custom UIButton that has an extra property for the associated image, and then just access the image through the button in the selector:
- (void)displayEditorForImage:(UIButton*)sender {
if([sender isKindOfClass:[YourCustomButtonClass class]]) {
UIImage* imageToEdit = ((YourCustomButtonClass*)sender).customImageProperty;
AFPhotoEditorController *editorController = [[AFPhotoEditorController alloc] initWithImage:imageToEdit];
[editorController setDelegate:self];
[self presentViewController:editorController animated:YES completion:nil];
}
}
Edit:
You seem to be confused as to how to make a UIButton call a method on when it is tapped. You need to add the object which defines the method as the button's target (in this case self), add the method as the selector, and to called the method when the button is tapped use the UIControlEventTouchUpInside. So your code would be:
[editButton addTarget:self action:#selector(displayEditorForImage:) forControlEvents:UIControlEventTouchUpInside];
Related
I am adding a button in UIScrollView in StoryBoard
Below is the code i am using.
-(void)addScrollView
{
for(int i=0;i<[array count];i++)
{
UIScrollView *subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, SUBSCROLLVIEW_WIDTH, SUBSCROLLVIEW_HEIGHT)];
UITextView *txtVwDetail = [[UITextView alloc] initWithFrame:CGRectMake(342, 0, TEXTVIEW_WIDTH, TEXTVIEW_HEIGHT)];
txtVwDetail.text = SAMPLE_STRING;
[self addSubScrollView:subScrollView];
[self.view addSubview:subScrollView];
[self.view addSubview:txtVwDetail];
}
}
-(void)addSubScrollView:(UIScrollView *)aSubScrollView
{
for(int i=0;i<[array count];i++)
{
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake(intBtnX, (aSubScrollView.frame.size.height - 80)/2, 50, 80);
[aButton setImage:[UIImage imageNamed:[self.items objectAtIndex:i]] forState:UIControlStateNormal];
**[aButton addTarget:self action:#selector(btnSubImageClicked) forControlEvents:UIControlEventTouchUpInside];**
aSubScrollView.contentSize = CGSizeMake(intScrollViewWidth, aSubScrollView.frame.size.height);
[aSubScrollView addSubview:aButton];
}
}
In addSubScrollView method I have added Button and its click event which is getting crashed.
-(void)btnSubImageClicked
{
NSLog(#"btnSubImageClicked");
}
I am having scenario as
MyMainViewController is the sourceViewController for my created customSegue which is the UIStoryboardSegue class
MyMainViewController having a UIView as PlaceHolderView in which I am adding MydestinationViewContoller's View which is this Scrollview
-(void)perform
{
BrowseScreenVC *srcObj = (BrowseScreenVC *)[self sourceViewController];
UIViewController *dstObj = (UIViewController *)[self destinationViewController];
for(UIView *vw in srcObj.viewPlaceHolder.subviews)
{
[vw removeFromSuperview];
}
NSLog(#"dest : %#",dstObj.view);
NSLog(#"destobj :%#",dstObj);
srcObj.currentViewController = dstObj;
[srcObj.viewPlaceHolder addSubview:[dstObj.view retain]];
}
UPDATE
With answer I also have to change the line
srcObj.currentViewController = dstObj;
to
srcObj.addChildViewController = dstObj;
to make it working
you have to add target as follow:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
#selector(), within these braces you have to provide the method that you want to perform. the ":" represents that the method has some argument. In this case the argument would be the button itself that is calling the method.
You have to implement your method then its signature would look like this
- (void)btnSubImageClicked:(id)sender{
// sender would be the button that is calling the method. you can use this object according to your requirements if you want.
// your code
}
if you want to call this method from somewhere else as well you can call it by passing sender argument nil. e.g [self btnSubImageClicked:nil];
Your action needs to accept an (id) sender argument, even if you are not using it:
-(void)btnSubImageClicked:(id) sender
{
NSLog(#"btnSubImageClicked");
}
In the addSubScrollView:
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Button target should like
-(void) btnSubImageClicked:(id)sender{}
try this.
Updated:-
Please correct your code,change this line
[aButton addTarget:self action:#selector(btnSubImageClicked:) forControlEvents:UIControlEventTouchUpInside];
Now working i checked.
Instead of
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
write this,
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
and for better practice always write this,
-(void) btnSubImageClicked:(id)sender{}
I have added multiple actions to one button
Play audiofile
Display array of views
Button is playing audiofile but not displaying views.
UIButton *playpauseButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playpauseButton addTarget:self action:#selector(playpauseAction:) forControlEvents:UIControlEventTouchUpInside];
[playpauseButton addTarget:self action:#selector(displayviewsAction:) forControlEvents:UIControlEventTouchUpInside];
playpauseButton.frame = CGRectMake(0, 0, 50, 50);
[playpauseButton setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[playpauseButton setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateSelected];
UIBarButtonItem *playpause = [[UIBarButtonItem alloc] initWithCustomView:playpauseButton];
Play Pause Action coding
-(void)playpauseAction:(id)sender
{
if
([audioPlayer isPlaying]){
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
} else {
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
}
}
DisplayviewsAction coding
- (void)displayviewsAction:(id)sender
{
CGRect pageViewRect = self.view.bounds;
pageViewRect = CGRectInset(pageViewRect, 30.0, 30.0);
self.pageViewController.view.frame = pageViewRect;
// Configure the page view controller
UIPageViewController *pageViewController = [[[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]autorelease];
NSArray *viewControllers = [NSArray arrayWithObject:pageViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self.view addSubview:self.pageViewController.view];
}
Any advice what i m missing in the code or doing wrong.
Thanks for help.
Here are some minor corrections you should make - they may not all help with the problem, but you never know.
Add a completion block here:
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
I don't remember for sure, but I think setViewControllers is done asynchronously - nothing cannot be added until after the completion handler is done. To add the block, you simply put a ^ and a block of code in (like a normal method):
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:^{
// your code here.
}];
This may fix the problem, but I cannot be sure until I can get back to my computer.
You should also put an NSLog at the beginning of every method, at least until you are done debugging. That way, you always know what is being called and what isn't. If it is not called, try removing the autorelease from the pageViewController - it may be released because it isn't being used.
I think the issue is in displayviewsAction, try something more simple like:
- (void) displayviewsAction:(id)sender
{
UIView* testView = [[UIView alloc] initWithFrame:CGRectInset(self.view.bounds, 30.0, 30.0)];
testView.backgroundColor = [UIColor greenColor];
[self.view addSubview:testView];
[testView release];
}
That should help you narrow down the problem. Depending on what your final aim is you might not need all those view controllers; instead consider UIView's transitionFromView... for the animation effects.
using this tutorial I set up a custom TabBar. Unfortunately the tutorial won't describe how to hide the custom TabBar in views you don't wanna display it.
In my customTabBar.h I defined
- (void) hideAlsoCustomTabBar;
- (void) showCustomTabBarAgain;
which are implemented as
- (void) hideAlsoCustomTabBar {
btn1.hidden = YES;
btn2.hidden = YES;
btn3.hidden = YES;
btn4.hidden = YES;
}
- (void) showCustomTabBarAgain {
btn1.hidden = NO;
btn2.hidden = NO;
btn3.hidden = NO;
btn4.hidden = NO;
}
Calling those inside CustomTabBar.m's viewDidAppear works fine and does exactly what I expect them to do. If I try to call those methods from the ViewController where I need to hide the TabBar like this
[customTabs hideAlsoCustomTabBar];
inside the initWithNibName OR viewDidLoad OR viewWillAppear, nothing will happen. I checked with NSLog, the method gets called, but when I read out the BOOL for any buttons .hidden attribute, it returns 0, when it should be 1 (for hidden==YES).
I don't know what's wrong with my setup. Is it possible these button's attributes are private by default as CustomTabBar inherits from UITabBarController and I can't set them? Or did I make a mistake in the call?
Thanks!
EDIT
The TabBar implementation as it is described in the tutorial
import "CustomTabBar.h"
#implementation CustomTabBar
#synthesize btn1,btn2,btn3,btn4;
- (void) viewDidAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self hideExistingTabBar];
[self addCustomElements];
}
- (void) hideExistingTabBar {
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UITabBar class]]) {
view.hidden = YES;
break;
}
}
}
- (void) addCustomElements {
//Initialise the two images for btnEinleitung, not selected and selected
UIImage *btnImage = [UIImage imageNamed:#"btnEinl.png"];
UIImage *btnImageSelected = [UIImage imageNamed:#"btnEinl_s.png"];
self.btnEinleitung = [UIButton buttonWithType:UIButtonTypeCustom];
btnEinleitung.frame = CGRectMake(0, 430, 86, 50);
[btnEinleitung setBackgroundImage:btnImage forState:UIControlStateNormal];
[btnEinleitung setBackgroundImage:btnImageSelected forState:UIControlStateSelected];
[btnEinleitung setTag:0];
[btnEinleitung setSelected:true];
//set other buttons
btnImage = [UIImage imageNamed:#"btnUbg.png"];
btnImageSelected = [UIImage imageNamed:#"btnUbg_s.png"];
self.btnUebungen = [UIButton buttonWithType:UIButtonTypeCustom];
btnUebungen.frame = CGRectMake(86, 430, 80, 50);
[btnUebungen setBackgroundImage:btnImage forState:UIControlStateNormal];
[btnUebungen setBackgroundImage:btnImageSelected forState:UIControlStateSelected];
[btnUebungen setTag:1];
/* do the same for btn3 and btn4*/
//add custom buttons to view
[self.view addSubview:btn1];
[self.view addSubview:btn2];
[self.view addSubview:btn3];
[self.view addSubview:btn4];
//setup event handlers so the buttonClicked method will respond to the touch up inside event
[btn1 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn2 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn3 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn4 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
//set tab to active according to the passed tag number
- (void) selectTab:(int)tabID {
switch (tabID) {
case 0:
[btnEinleitung setSelected:TRUE];
[btnUebungen setSelected:FALSE];
[btnTipps setSelected:FALSE];
[btnBrauchtum setSelected:FALSE];
btnEinleitung.userInteractionEnabled = NO;
btnUebungen.userInteractionEnabled = YES;
btnTipps.userInteractionEnabled = YES;
btnBrauchtum.userInteractionEnabled = YES;
break;
case 1:
[btnEinleitung setSelected:FALSE];
[btnUebungen setSelected:TRUE];
[btnTipps setSelected:FALSE];
[btnBrauchtum setSelected:FALSE];
btnEinleitung.userInteractionEnabled = YES;
btnUebungen.userInteractionEnabled = NO;
btnTipps.userInteractionEnabled = YES;
btnBrauchtum.userInteractionEnabled = YES;
break;
// and so on for 2 and 3
}
self.selectedIndex = tabID;
}
//get the tag of the sender/pressed button, call the function selectTab
- (void) buttonClicked:(id)sender {
int tagNum = [sender tag];
[self selectTab:tagNum];
}
EDIT
As described below, I have 4 Tabs in a Tabbar which was generated with IB, added Navigation Controller with their ViewControllers, made Outlets for those and connected them in IB.
Clicking on the second Tab (e.g. sndMenuVC) opens a view with 4 buttons. Clicking one of these buttons leads to another view (e.g. detailVC) in which I don't want the TabBar to be displayed. detailVC has it's own nib.
Opening detailVC happens with the button's action declared like this
- (IBAction) openFourth:(id)sender{
detailVC *detailView = [[detailVC alloc] initWithNibName:#"detailVC" bundle:nil andSender:kFourthButtonSender];
[self.navigationController pushViewController:detailView animated:YES];
[detailView release];
}
As this is a custom initWithNibName, this is how I implemented it
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andSender: (NSString *)calledByButton{
self.callingButton = calledByButton;
[super initWithNibName:#"detailVC" bundle:nil];
return self;
}
SO I basically just set a global variable "callingButton" according to the transmitted sender and call the "normal" initWithNibName afterwards.
This all works fine.
If I try to call hideAlsoCustomTabBar, and NSLog the value of btn1.hidden it returns 0 when called from detailVC, but returns 1 when called from within CustomTabBar and actually hides the buttons.
I have customTabs as IBOutlet if needed, but don't know if this is connected correctly to the TabBarController of type CustomTabBar.
Hope this helps to understand me :) If you need any other information, just let me know.
Thanks!
I have written a follow up to my RXCustomTabBar tutorial which should answer your questions. I don't see any point reproducing it in full here.
Hiding your New Custom UITabBar (RXCustomTabBar follow up)
Let me know if you have any questions,
Oli
if you want to hide the tabBar you can simply, in your view controller, call
[[[self tabBarController] tabBar] setHidden:YES];
In RXCustomTabBar.m file addCustomElements function is called from viewDidAppear.
-(void)addCustomElements
{
.
.
.
.
// Add my new buttons to the view
// Following lines are adding buttons to the view. Put your condition here according to requirement so that it will check and add buttons accordingly.
[self.view addSubview:btn1];
[self.view addSubview:btn2];
[self.view addSubview:btn3];
[self.view addSubview:btn4];
.
.
.
.
}
Hope this helps.
Update
//Add following function in RXCustomTabBar.m
-(void)hideButtons
{
btn1.hidden = YES;
btn2.hidden = YES;
btn3.hidden = YES;
btn4.hidden = YES;
}
- (void)selectTab:(int)tabID
{
switch(tabID)
{
case 0:
[btn1 setSelected:true];
[btn2 setSelected:false];
[btn3 setSelected:false];
[btn4 setSelected:false];
break;
case 1:
[self hideButtons]; //Call function for hiding buttons like this.
[btn1 setSelected:false];
[btn2 setSelected:true];
[btn3 setSelected:false];
[btn4 setSelected:false];
break;
}
self.selectedIndex = tabID;
}
Let say you want to hide buttons on 2nd View Controller. So I have called [self hideButtons] in case 1 index.
This will Hide all the tabbar buttons. And again Viceversa you have to put diff condition to show those tab buttons.
Does this make sense ?
Since the custom tabs exists already at the point this method is called. You should assign it to detailView's customTabs property here.
- (IBAction) openFourth:(id)sender{
detailVC * detailView = [[detailVC alloc] initWithNibName:#"detailVC" bundle:nil andSender:kFourthButtonSender];
detailView.customTabs = **theExistingCustomTabsObject**;
[self.navigationController pushViewController:detailView animated:YES];
[detailView release];
}
Orignal Answer
As the reference to the subclass of the UITabBarController is nil, you will have to set it properly. If you have used IB to set the view controllers, go to the NIB file. Right click on the view controller, select the customTabs outlet and connect it to the customTabBar object holding the view controllers.
If you've created the view controllers programmatically then somewhere after adding the view controllers to the tab bar and before releasing the view controllers, do this,
viewController.customTabs = self.customTabBarObject;
I'm dynamically adding image buttons to some scrollview. They all point at one longPressHandler. Now, how do I get which button was pressed? The [sender tag] gives me the tag of longGestureRecognizer that I added to button and I can't manually set that tag.
for (...) {
UIButton *button = [[UIButton alloc] init];
button.tag = w + h * 3;
[button addTarget:self action:#selector(imageButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *gest = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(imageButtonLongPress:)];
gest.minimumPressDuration = 1;
gest.delegate = self;
[button addGestureRecognizer:gest];
[gest release];
[scrollView addSubview:button];
[button release];
}
- (void) imageButtonLongPress:(id)sender {
// how to get button tag here?
}
There is a view property in the UIGestureRecognizer which returns the view that recognizer is attached to. I think that is your best bet.
- (void) imageButtonLongPress:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender;
int tag = recognizer.view.tag;
}
In your action you have to type cast your sender in gesture and then type cast its view to a button then get button's tag as -
UILongPressGestureRecognizer *gest = (UILongPressGestureRecognizer *)sender;
UIButton *button = (UIButton*)[gest view];
NSLog(#"%d",[button tag]);
is there any way to hide an UIButton until the UIImageView is pressed??
When the picture is pressed I need to show the back Button, like it works at the Photo App on the iPhone???
Here is the code of my UIButton:
- (void)viewDidLoad {
[super viewDidLoad];
[self ladeImage];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 40, 40);
[btn addTarget:self action:#selector(goToViewA) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:#"<<" forState:UIControlStateNormal];
[self.view addSubview:btn];
}
First step : btn.hidden = YES
Then you have to subclass the UIImageView to react to its touchesEnded: event and change the hidden property of your button there. For that, the proper way is to create a protocol (with a viewTouched method). Implement that protocol in the viewController containing your button and you ImageView. Add a delegate propery to the subclassed ImageView (i.e. id<MyCustomProtocol> _delagate;) and assign the view controller to this propery.
btn.hidden = YES;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image name"]];
imageView.userInteractionEnabled = YES; // here to enable touch event
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGestureRecongizer:)]; // handleTapGestureRecongizer is method will call when tap even fire
[imageView addGestureRecognizer:tap]; // Add Tap gesture recognizer to image view
[tap release], tap = nil;
[self.view addSubview:imageView];
[imageView release], imageView = nil;
Method handlerTapGestureRecognizer:
- (void)handleTapGestureRecongizer:(UITapGestureRecognizer *)gestureRecognizer{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
btn.hidden = NO;
}
}
have fun!