I have created a UIButton and UIImageView where the button frame is set same as image frame size. What I'm willing to do is once I touch the image it should PopOver. Button is set with action.The problem is that it is displaying only image once I touch it is not Poping up.
What is wrong with my code?
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10,100, 100)];
imageView.image=[UIImage imageNamed:#"abc.jpg"];
[self.view addSubview:imageView];
imageView.userInteractionEnabled = YES;
UIButton *imageButton = [[UIButton alloc]init];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[imageButton release];
[imageView release];
}
-(void)imageTapped:(UIButton*)in_sender {
UIViewController *popoverContent = [[UIViewController alloc] init];
CGRect theScreenFrame = [[UIScreen mainScreen] bounds];
popoverContent.view.frame = CGRectMake(theScreenFrame.origin.x, theScreenFrame.origin.y,100, 100);
popoverContent.view.backgroundColor = [UIColor whiteColor];
popoverContent.contentSizeForViewInPopover = CGSizeMake(300, 300);
[popoverContent.view addSubview:imageButton];
if(m_DetailPopover) {
[m_DetailPopover release];
m_DetailPopover = nil;
}
UIPopoverController m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverContent release];
[m_DetailPopover presentPopoverFromRect:imageButton.frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Might be the problem is a typo in the code:
UIPopoverController *m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
Also pls note that you cannot reference imageButton in imageTapped, because
you release it in viewDidLoad.
Dont' add an image view as subview to a button or vice versa. Just assign the image (not the image view) as background image to the button.
Your UIImageView is front of the UIButton, not allowing to get the button action. Why don't you create a custom button with your image?
Do like this:
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setImage:[UIImage imageNamed:#"abc.jpg"]];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[imageButton release];
[imageView release];
EDIT
UIPopoverController *m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[m_DetailPopover presentPopoverFromRect:imageButton.frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[popoverContent release];
Related
In my app I have a UINavigationController with a UISplitViewController as rootViewController. The masterViewController of this UISplitViewController sets a UIView with a UITextField centered inside it as titleView. This is wat it looks like in the storyboard.
- (void)viewDidLoad {
[super viewDidLoad];
self.titleView = [[UIView alloc] initWithFrame:CGRectMake((self.view.frame.size.width-((self.view.frame.size.width/2)+150))/2, 0, (self.view.frame.size.width/2)+150, 30)];
self.rightButton = [[UIButton alloc] init];
[self.rightButton setImage:newImage forState:UIControlStateNormal];
[self.rightButton addTarget:self action:#selector(barButtonRight:) forControlEvents:UIControlEventTouchUpInside];
self.rightButton.frame = CGRectMake(0, 0, 30, 30);
self.rightButton.tintColor = [UIColor whiteColor];
[self.rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithCustomView:self.rightButton];
self.splitViewController.navigationItem.rightBarButtonItem = rightButton;
self.textField = [[UITextField alloc]init];
if (IDIOM == IPAD) {
self.textField.frame = CGRectMake(0, 0, self.titleView.frame.size.width, 30);
} else {
self.textField.frame = CGRectMake(65, 0, (self.view.frame.size.width-20)-110, 30);
}
self.textField.backgroundColor = [UIColor purpleColor];
if (IDIOM == IPAD) {
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 15, 20)];
self.textField.leftView = paddingView;
self.textField.leftViewMode = UITextFieldViewModeAlways;
}
[self.titleView addSubview:self.textField];
self.splitViewController.navigationItem.titleView = self.titleView;
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
Now, when a the right button is pressed a strange thing happens.
- (IBAction)barButtonRight:(id)sender {
[self performSegueWithIdentifier:#"showDetail" sender:self];
}
The UITextField is pushed all the way to the left inside the UIView. I commented out most of my viewDidLoad code and this is still happening. Any ideas as to what's causing this?
I have container view, where I add some image and button.
Container view is property of UIView.
I'll add my Container View to ScrollView like this:
#property (nonatomic,strong) UIView *containerView;
..
containerView = [[UIView alloc] init];
for (int i=0;i<5;i++) {
UIImageView *whiteBack = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 235-height, 385-height-height)];
whiteBack.center = CGPointMake(_scrollView.frame.size.width * i+_scrollView.frame.size.width/2, self.view.bounds.size.height/2-131+height);
whiteBack.backgroundColor = [UIColor darkGrayColor];
whiteBack.layer.cornerRadius = 3;
whiteBack.layer.masksToBounds = YES;
[containerView addSubview:whiteBack];
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 228-height, 340-height-height)];
img.center = CGPointMake(_scrollView.frame.size.width * i+_scrollView.frame.size.width/2, self.view.bounds.size.height/2-150+height);
img.image = [UIImage imageNamed:[NSString stringWithFormat:#"poster0%i.jpg",i+1]];
[containerView addSubview:img];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
infoButton.frame = CGRectMake(233, 0, 25, 25);
infoButton.center = CGPointMake(_scrollView.frame.size.width * i+_scrollView.frame.size.width/2-100, 325-height);
[infoButton addTarget:self action:#selector(flipImage:) forControlEvents:UIControlEventTouchUpInside];
infoButton.tag = i;
infoButton.backgroundColor = [UIColor clearColor];
[infoButton setImage:[UIImage imageNamed:#"upload-50"] forState:UIControlStateNormal];
[infoButton setTintColor:[UIColor whiteColor]];
[containerView addSubview:infoButton];
}
[self.scrollView addSubview:containerView];
///
- (void) flipImage :(id) sender {
NSLog(#"infoButton pressed:%i",[sender tag]);
}
but when I pressed button nothing happens!
Your container view has a zero frame (because you just did [[UIView alloc] init];). This means that it never receives any touches because you can never hit it. This goes for the subviews too.
The reason you see the subviews is that views, by default, do not clip drawing to their bounds.
To fix, set the frame of your container view to an appropriate size for the subviews you're adding.
In my project I want to show a first run view when starting the app for te first time. To do this I added a UIView to my mainViewCntroller.m. To dismiss this (overlayed) view I put a button on the view called acceptButton. What code do I have to add to the Button to remove this view from the stack?
What do I do wrong?
Here's my code:
- (void) firstRun {
if (((AppDelegate*)[UIApplication sharedApplication].delegate).firstRun)
{
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
NSLog(#"%f", height);
CGRect myFrame = CGRectMake(0, 0, width, height);
UIView *myView = [[UIView alloc] initWithFrame:myFrame];
myView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
myView.tag = 12345;
[self.view addSubview:myView];
// Create a ScrollView and a label
UIScrollView *discScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20.0f, 0.0f, self.view.frame.size.width - 20, self.view.frame.size.height -70)];
discScroll.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UILabel *discLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,0,0)];
discLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
NSString *labelText = NSLocalizedString (#"InfoText",#"");
[discLabel setText:labelText];
// Tell the label to use an unlimited number of lines
[discLabel setNumberOfLines:0];
[discLabel setNumberOfLines:0];
[discLabel setBackgroundColor:[UIColor clearColor]];
[discLabel setFont:[UIFont boldSystemFontOfSize:17]];
discLabel.textColor = [UIColor colorWithRed:255 green:255 blue:255 alpha:1.0];
//[infoLabel sizeToFit];
CGSize infoLabelSize = [discLabel.text sizeWithFont:discLabel.font
constrainedToSize:CGSizeMake(discScroll.frame.size.width, 5000)
lineBreakMode:UILineBreakModeWordWrap];
discLabel.frame = CGRectMake(0, 0, infoLabelSize.width, infoLabelSize.height);
discScroll.contentSize = infoLabelSize;
[discScroll addSubview:discLabel];
[self.view addSubview:discScroll];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
acceptButton.frame = CGRectMake(110, [[UIScreen mainScreen] bounds].size.height - 74, 100, 44);
// position in the parent view and set the size of the button
[acceptButton setTitle:#"Click Me!" forState:UIControlStateNormal];
// add targets and actions
[acceptButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
// add to a view
[self.view addSubview:acceptButton];
}
}
-(IBAction)buttonClicked:(id)sender
{
[[self.myView viewWithTag:12345] removeFromSuperview];
}
In my mainViewController.h is the following property:
#property (weak, nonatomic) IBOutlet UIView *myView;
EDIT I've post the complete code. Maybe something else is in the way.
Ive written it in Xcode, following Code works for me.
Ive opened a new XCode Project (Single View based), and just added following Code:
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
myView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
myView.tag = 12345;
[self.view addSubview:myView];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
acceptButton.frame = CGRectMake(0, 0, 100, 44);
[acceptButton setTitle:#"Click Me!" forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
[myView addSubview:acceptButton];
[myView release];
}
- (void)buttonClicked{
[[self.view viewWithTag:12345] removeFromSuperview];
}
This worked for me in iPhone Simulator.... Just this code in the MainViewController.m nothing else... Just give it a try, hope it works for you too :-)
[acceptButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
when your method is called acceptButton, change to
[acceptButton addTarget:self action:#selector(acceptButton:) forControlEvents:UIControlEventTouchUpInside];
your target is set to buttonClicked but you are using acceptButton
[acceptButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)buttonClicked:(id)sender
{
[self.myView removeFromSuperview];
}
The problem lies with the [acceptButton addTarget:self action:#selector(buttonClicked:) line. Change buttonClicked to your method acceptButton: in that call.
[acceptButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
The exception is clear, there is no function named "buttonClicked"
Just change the part of your code with below code;
[acceptButton addTarget:self action:#selector(acceptButton:) forControlEvents:UIControlEventTouchUpInside];
just give it a tag...
UIView *myView = [[UIView alloc] initWithFrame:myFrame];
myView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
myView.tag = 12345;
[self.view addSubview:myView];
[myView release];
-(IBAction)acceptButton:(id)sender{
[[self.view viewWithTag:12345] removeFromSuperview];
}
Also change
action:#selector(buttonClicked:)
to
action:#selector(acceptButton:)
After looking through the post on this simple topic I still can not figure out what I've done wrong here. I am trying to make the buttons loop through the same action in the same viewController.
When the view comes onto the screen the buttons do not click (or at least the NSLog does not write to the console which it does the first time it enters this code.)
- (IBAction)answer: (id) sender{
NSLog(#"The Number is: %d\n",qNumber);
qNumber+=1;
UIView *newView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
[newView setUserInteractionEnabled:TRUE];
UIImage *buttonImage = [UIImage imageNamed:#"pink_button.png"];
UIImageView *buttonImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(23, 294, 72, 37)] autorelease];
[buttonImageView setImage:buttonImage];
UILabel* buttonLabel = [[[UILabel alloc] initWithFrame:CGRectMake(23, 294, 72, 37)] autorelease];
buttonLabel.text = #"newLow";
buttonLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size: 15.0];
buttonLabel.textColor = [UIColor blackColor];
buttonLabel.backgroundColor = [UIColor clearColor];
buttonLabel.textAlignment = UITextAlignmentCenter;
lowButton = [UIButton buttonWithType:UIButtonTypeCustom];
[lowButton addSubview:buttonImageView];
[lowButton addSubview:buttonLabel];
[lowButton addTarget:self action:#selector(answer:) forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:lowButton];
self.view = newView;
}
Thanks for any help you can provide...even if I missed something simple :-)
Latest Updated Code:
lowButton = [UIButton buttonWithType:UIButtonTypeCustom];
[newView addSubview:buttonImageView];
[newView addSubview:buttonLabel];
[lowButton addTarget:self action:#selector(answer:) forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:lowButton];
[self.view bringSubviewToFront:lowButton];
self.view = newView;
Still when the button is pressed it does not enter the action code.
You button needs a frame. You can't tap a frameless button.
lowButton.frame = CGRectMake(23, 294, 72, 37);
Also, when you add label and image to that button, their frame should have x and y 0.
UIImageView *buttonImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 72, 37)] autorelease];
...
UILabel* buttonLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 72, 37)] autorelease];
...
But may I ask why you are adding new UIImageView and UILabel to UIButton when it has it's label and background view properties?
Edit here is a cleaned-up code for you:
UIView *newView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
lowButton = [UIButton buttonWithType:UIButtonTypeCustom];
[lowButton setImage:[UIImage imageNamed:#"pink_button.png"] forState:UIControlStateNormal];
[lowButton setTitle:#"newLow" forState:UIControlStateNormal];
[lowButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[lowButton.titleLabel setFont:[UIFont boldSystemFontOfSize:15.0]];
[lowButton addTarget:self action:#selector(answer:) forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:lowButton];
self.view = newView;
Notice I also removed [newView setUserInteractionEnabled:TRUE]; as it's not needed since it's enabled by default.
Your custom button's subviews are covering the button, so it does not get any clicks.
Try adding all the subviews to newView rather than to lowButton (including lowButton itself) and then call
[self.view bringSubViewToFront:lowButton];
I have added a few buttons to the right side of the navigation bar with the following:
UIView* customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
customView.backgroundColor = [UIColor clearColor];
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 45, 44);
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.backgroundColor = [UIColor clearColor];
[button setImage:[UIImage imageNamed:#"toc.png"] forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(tableOfContentsAction) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:button];
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(50, 0, 45, 44);
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.backgroundColor = [UIColor clearColor];
[button setImage:[UIImage imageNamed:#"bookmark.png"] forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(bookmarkButtonAction) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:button];
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[customView release];
[segmentBarItem release];
This works well. For both buttons I show a popOver as shown below
- (void) bookmarkButtonAction
{
BookmarksViewController* content = [[BookmarksViewController alloc] initWithOrientation:lastOrientation selectedPage:selectedPage];
UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:content];
CGSize size = content.view.frame.size;
aPopover.popoverContentSize = size;
aPopover.delegate = self;
self.bookmarksPopoverVC = content;
self.bookmarksPopoverVC.popUpController = aPopover;
[content release];
[aPopover presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
[aPopover release];
bookmarksShowing = YES;
}
The problem is that I am using presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem and this shows the top arrow in the middle of the two buttons. How can I attach the arrow to each button?
instead of using this line:
aPopover presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem
You may better try this line:
aPopover presentPopoverFromBarButtonItem:sender
I think that would solve your problem
try this:
- (IBAction)products:(id)sender {
UIButton* btn = (UIButton *)sender;
[productsPopover presentPopoverFromRect:[btn bounds] inView:btn permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Works like a charm