Recognize a UIButton Tap inside a UIScrollView - objective-c

I have a UIScrollView into which I add UIImageViews dynamically.
On the storyboard
After running the program
The code for adding an image is on my custom class. The class isn't assigned to any view:
- (id)initWithModel:(UIScrollView *)scroller page:(NSInteger)page image:(UIImage*)image{
self = [super init];
if (self) {
_scrollView = scroller;
_imageScrollIndex = page;
_image = image;
_frame = _scrollView.bounds;
_frame.origin.x = _frame.size.width * _imageScrollIndex;
_frame.origin.y = 0.0f;
_frame = CGRectInset(_frame, 10.0f, 0.0f);
_imageView = [[UIImageView alloc] initWithImage:_image];
_imageView.contentMode = UIViewContentModeScaleAspectFit;
_imageView.frame = _frame;
//adding delete image button
CGRect frame = _imageView.frame;
frame.origin.x = frame.size.width/2;
frame.origin.y = -frame.size.height/2+45;
//_imageView.userInteractionEnabled = YES;
UIButton *deleteImgButton = [[UIButton alloc] initWithFrame:frame];
deleteImgButton.userInteractionEnabled = YES;
[deleteImgButton addTarget:self action:#selector(clickedDeleteButton:)forControlEvents:UIControlEventTouchUpInside];
[deleteImgButton setImage:[UIImage imageNamed:#"close.png"] forState:UIControlStateNormal];
[_imageView addSubview:deleteImgButton];
////
[_scrollView addSubview:_imageView];
}
return self;
}
- (void)clickedDeleteButton:(UIButton*)button
{
printf("hi:\n");
}
I want to be:
Be able to recognize scroll event (Thus I think I need to keep the userinteractionenabled YES for the scrollView
Be able to recognize a tap on the delete button of the image
Any ideas how?

_scrl_ipad.contentSize = CGSizeMake(768,273 * temp);
_scrl_ipad.showsVerticalScrollIndicator=NO;
UIButton *btn_scrl=[UIButton buttonWithType:UIButtonTypeCustom];
[btn_scrl setFrame:CGRectMake(0,0, 328, 243)];
btn_scrl.tag=i-1;
[btn_scrl addTarget:self action:#selector(btn_scrl_tag:) forControlEvents:UIControlEventTouchUpInside];
[_scrl_ipad addSubview:btn_scrl];
-(IBAction)btn_scrl_tag:(id)sender
{
UIButton *btn = (UIButton *)sender;
NSLog(#"%d",btn.tag);
}

Related

Can't see a new subview

All I am trying to do is add a new view to the content view of my NSWindow instance. When I do the following I do not see the new view (which should be black and take up the entire window). What am I doing wrong?
(done in response to a button click)
NSRect frameRect = [self.window frame];
frameRect.origin = NSZeroPoint;
NSView *view = [[NSView alloc] initWithFrame:frameRect];
view.wantsLayer = YES;
view.layer.backgroundColor = [NSColor blackColor].CGColor;
[self.window.contentView addSubview:view];
I've set up a simple project with a push button inside a ViewController and got a warning for accessing self.window. When using self.view.windowthe warning went away and your provided code works as expected.
Updated code
NSRect frameRect = [self.view.window frame];
frameRect.origin = NSZeroPoint;
NSView *view = [[NSView alloc] initWithFrame:frameRect];
view.wantsLayer = YES;
view.layer.backgroundColor = [NSColor blackColor].CGColor;
[self.view.window.contentView addSubview:view];
Update
Assuming that you're using an instance of WindowController where you're adding a button programmatically, your code works as expected.
#implementation WindowController
- (void)windowDidLoad
{
[super windowDidLoad];
CGRect buttonRect = CGRectMake(self.window.frame.size.width / 2 - 50,
self.window.frame.size.height / 2,
100,
50);
NSButton *button = [[NSButton alloc] initWithFrame:NSRectFromCGRect(buttonRect)];
[button setTitle: #"Click me!"];
[button setTarget:self];
[button setAction:#selector(buttonPressed)];
[self.window.contentView addSubview:button];
}
- (void)buttonPressed
{
NSRect frameRect = [self.window frame];
frameRect.origin = NSZeroPoint;
NSView *view = [[NSView alloc] initWithFrame:frameRect];
view.wantsLayer = YES;
view.layer.backgroundColor = [NSColor blackColor].CGColor;
[self.window.contentView addSubview:view];
}
An instance of NSViewController ain't got a property of window - only NSWindowController has one.

Add texfield in runtime in IOS

I want to make an "add" button to add as many textfields as i want in my scroll view.
I did this already
UITextField *text=[[UITextField alloc]initWithFrame:CGRectMake(50,50,200,200)];
[self.scrollView addSubview:text];
But is not working.
Thanks!
If this is your complete button code:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
// add this
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
// continue
[self.mainScroll addSubview:button];
Then add this somewhere:
- (void) buttonPressed:(UIButton *)button {
UITextField *text=[[UITextField alloc]initWithFrame:CGRectMake(50,50,200,200)];
text.backgroundColor = [UIColor greenColor]; // just to make sure it's showing up.
[self.scrollView addSubview:text];
}
First create common function like this,
-(void)setTextfieldStyle:(UITextField *)pTmpTextField
{
pTmpTextField.borderStyle = UITextBorderStyleRoundedRect;
pTmpTextField.font = [UIFont systemFontOfSize:15];
pTmpTextField.placeholder = #"First Name";
pTmpTextField.autocorrectionType = UITextAutocorrectionTypeNo;
pTmpTextField.keyboardType = UIKeyboardTypeDefault;
pTmpTextField.returnKeyType = UIReturnKeyDone;
pTmpTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
pTmpTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
pTmpTextField.delegate = self;
}
and use this for creating UITextFiled,
int y = 0;
for(int i=0;i < 5;i++)
{
UITextField *txtTemp=[[UITextField alloc]initWithFrame:CGRectMake(0, y, 300, 31)];
txtTemp.tag = i;
[self setTextfieldStyle:txtTemp];
[self.view addSubview:txtTemp];
[txtTemp release];
y+=36;
}
This is UITextField's delegate method,
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(#"%#",textField.text);
}
Hope this works for you as this works for me. only keep this in mind that add the text fields to your scroll view.
In the example am adding them to my view!

UIButton touch up inside event only fired if done in title

I am customizing a UITableViewCell with several subviews:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_mainView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40.0f)];
_hiddenOptionsView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40.0f)];
_menuView = [[CellMenuView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 20.0f)];
[self addSubview:_menuView];
[self addSubview:_hiddenOptionsView];
[self addSubview:_mainView];
}
return self;
}
The class CellMenuView is a UIView subclass which has two UIButtons with their counterpart target actions setup on initialization:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIImageView *background = [[UIImageView alloc] initWithFrame:frame];
[background setImage:[UIImage imageNamed:#"cell_menu_bg.png"]];
[self addSubview:background];
CGFloat buttonX = frame.origin.x;
CGFloat buttonY = frame.origin.y + 3.0f;
CGFloat buttonWidth = frame.size.width / 2.0f;
CGFloat buttonHeight = 10.0f;
_editButton = [UIButton buttonWithType:UIButtonTypeCustom];
_editButton.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight);
_editButton.backgroundColor = [UIColor clearColor];
_editButton.titleLabel.shadowColor = [UIColor blackColor];
_editButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.5f);
_editButton.titleLabel.font = [UIFont boldSystemFontOfSize:22.0f];
[_editButton setTitle:#"Edit" forState:UIControlStateNormal];
[_editButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_editButton addTarget:self action:#selector(editButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_editButton];
_fireButton = [UIButton buttonWithType:UIButtonTypeCustom];
_fireButton.frame = CGRectMake(buttonWidth, buttonY, buttonWidth, buttonHeight);
_fireButton.backgroundColor = [UIColor clearColor];
_fireButton.titleLabel.shadowColor = [UIColor blackColor];
_fireButton.titleLabel.shadowOffset = CGSizeMake(0.0f, -1.5f);
_fireButton.titleLabel.font = [UIFont boldSystemFontOfSize:22.0f];
[_fireButton setTitle:#"Fire" forState:UIControlStateNormal];
[_fireButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_fireButton addTarget:self action:#selector(fireButton:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_fireButton];
return self;
}
}
I have implemented the target action methods but they aren't being executed. Instead, didSelectRowAtIndexPath: takes precedence over the touch up events inside buttons every time I pressed one of them.
The only way I have been able to fire the events on buttons is making sure that one of the letters in UIButton's title is touched (using the simulator, of course).
I must say that _menuView is hidden behind the other subviews and shown below the cell when a custom accessory button in cell is pressed. It appears by modifying the Y origin and disappears by setting it to 0.0f again.
I think it may be related to the view hierarchy, because I haven't had any problems in the past by adding buttons directly to the cell. But I'm just guessing here.
How can I make the events on buttons take precedence over the didSelectRowAtIndexPath: method?
Thanks!
Implement
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
And return nil for the indexPath you don't want selected; this will prevent didSelectRowAtIndexPath from being called on that cell, and (hopefully), your custom action will be called.
Update: After implementing this myself (adding borders to the buttons), this is what I have.
The code to achieve this (which is different than yours), is as follows:
CellMenuView.m
self.backgroundColor = [UIColor blackColor];
_editButton.layer.borderColor = [UIColor whiteColor].CGColor;
_editButton.layer.borderWidth = 2;
_fireButton.layer.borderColor = [UIColor whiteColor].CGColor;
_fireButton.layer.borderWidth = 2;
UITableViewCell subclass
// Change in height to make it taller
_menuView = [[TestBtn alloc] initWithFrame:CGRectMake(0.0f, 20.0f, 320.0f, 60.0f)];
UITableViewController subclass
self.tableView.rowHeight = 100;
After testing, mine works as expected. If I click within the white squares, the button action is performed as normal, and didSelectRowAtIndexPath is not called. didSelectRowAtIndexPath is only called when I click outside of the buttons.
I think the issue here might be your button heights/frames, as well as your row height. Add borders to your buttons, to check its clickable area, and increase the height of the button to increase the clickable area.

UIScrollView paging with buttons

i was wondering how you create a paging UIScrollView with buttons as the objects?
So far i have figured out to make a similar UIScrollView with images instead which looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *pictures = [NSArray arrayWithObjects: [UIImage imageNamed:#"nr1"], [UIImage imageNamed:#"nr2"], nil];
for (int i = 0; i < pictures.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
subview.image = [pictures objectAtIndex:i];
[self.scrollView addSubview:subview];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * pictures.count, self.scrollView.frame.size.height);
}
Any tutorials would be appreciated :)
You will just add buttons instead of images
Replace this
UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
subview.image = [pictures objectAtIndex:i];
[self.scrollView addSubview:subview];
With
UIButton *subview = [UIButton buttonWithType:UIButtonTypeRoundedRect];
subview.frame = frame;
[subview setTitle:#"Test" forState:UIControlStateNormal];
[self.scrollView addSubview:subview];

How does autoresizing mask work?

I've found a lot of information on autoresizing but none has been able to solve my problem. I have a ViewController (RAViewController) who calls a view in its loadView method like so:
- (void)loadView
{
// Set Navigation Bar Title
self.navigationItem.title = #"RA";
// Add Background view
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Add RAView
RAView *rAView = [[RAView alloc] initWithFrame:self.view.frame Controller:self];
[self.view rAView];
}
The view it calls (RAView) looks like this:
- (id)initWithFrame:(CGRect)frame Controller:(RAViewController *)Controller
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.autoresizesSubviews = YES;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backgroundColor = [[UIColor alloc] initWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
controller = Controller;
// Draw Architecture View
[self drawArchitectureView];
}
return self;
}
-(void)drawArchitectureView {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, self.frame.size.width - 20, 50);
[button setBackgroundColor:[UIColor grayColor]];
[button setTitle:#"Overview" forState:UIControlStateNormal];
[self addSubview:button];
}
For some reason I can't get autoresizing mask to resize the button width when the device is landscape. Any help is greatly appreciated.
If you want it to keep the same height, but just stay fully centered, 10.0 from the left and right, try:
-(void)drawArchitectureView {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, self.frame.size.width - 20, 50);
button.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
[button setBackgroundColor:[UIColor grayColor]];
[button setTitle:#"Overview" forState:UIControlStateNormal];
[self addSubview:button];
}