Connect a UITapGestureRecognizer to a UIView - objective-c

I'm trying to connect a gesture to a UIView so I can tap on the object, but it is not working. What am I doing wrong?
Shape.h
#import <UIKit/UIKit.h>
#interface Shape : UIView;
- (id) initWithX: (int)xVal andY: (int)yVal;
#end
Shape.m
#import "Shape.h"
#implementation Shape
- (id) initWithX:(int )xVal andY:(int)yVal {
self = [super init];
UIView *shape = [[UIView alloc] initWithFrame:CGRectMake(xVal, yVal, 10, 10)];
shape.backgroundColor = [UIColor redColor];
shape.userInteractionEnabled = YES;
[self addSubview:shape];
return self;
}
#end
MODIFIED CODE: The following code is in the main ViewController. I have removed the UITapGestureRecognizer from the Shape class. The code works if I make the following change, but then it is 'box' that responds to the tap gesture, not 'shape':
[shape addGestureRecognizer:tap];
to
[box addGestureRecognizer:tap];
- (void)handlerTap:(UITapGestureRecognizer *)recognizer {
//CGPoint location = [recognizer locationInView:[recognizer.view superview]];
NSLog(#"Success");
}
-(void)drawShapes{
NSLog(#"Draw");
if(!box){
box = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight-100)];
box.backgroundColor = [UIColor colorWithRed: 0.8 green: 0.8 blue: 0.0 alpha:0.2];
[self.view addSubview:box];
}
for (int i = 0; i<5; i++) {
int x = arc4random() % screenWidth;
int y = arc4random() % screenHeight;
Shape * shape =[[Shape alloc] initWithX:x andY:y ];
[box addSubview:shape];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
[tap setNumberOfTapsRequired:1];
[tap addTarget:self action:#selector(handlerTap:)];
[box addGestureRecognizer:tap];
}
}
SOLUTION: I have learned that
self = [super init];
needs to be changed to include a CGRECT that defines the boundaries of the view that *shape is placed into.
self = [super initWithFrame:CGRectMake(xVal, yVal, 10, 10)];
Also, *shape needs to be placed at 0,0 to ensure its correct placement within its parent.
UIView *shape = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
#import "Shape.h"
#implementation Shape
- (id) initWithX:(int )xVal andY:(int)yVal {
self = [super initWithFrame:CGRectMake(xVal, yVal, 10, 10)];
UIView *shape = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
shape.backgroundColor = [UIColor redColor];
shape.userInteractionEnabled = YES;
[self addSubview:shape];
return self;
}
#end

You should set the target of the gesture recognizer to self, not the view, because you implemented the handlerTap: method in the Shape class.

Related

How to set UIImageView image added in viewForHeaderInSection and set in another Method

How to set UIImageView image added in viewForHeaderInSection and set in another Method.
- (NSInteger)numberOfSectionsInTableView:(TQMultistageTableView *)mTableView
{
return 4;
}
- (UIView *)mTableView:(TQMultistageTableView *)mTableView viewForHeaderInSection:(NSInteger)section;
{
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 90)];
header.layer.backgroundColor = [UIColor whiteColor].CGColor;
header.layer.masksToBounds = YES;
UILabel *sectionTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, self.view.frame.size.width - 110, 70)];
sectionTitleLabel.text = [sectionTitleArray objectAtIndex:section];
sectionTitleLabel.textAlignment = NSTextAlignmentCenter;
sectionTitleLabel.font = [UIFont fontWithName:#"Helvetica-Neue" size:15];
sectionTitleLabel.numberOfLines = 0;
sectionTitleLabel.contentMode = NSLineBreakByWordWrapping;
[header addSubview:sectionTitleLabel];
UIImageView *locationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width - 90, 0, 90, 90)];
locationImageView.image = [locationImageArray objectAtIndex:section];
locationImageView.backgroundColor = [UIColor brownColor];
[header addSubview:locationImageView];
UILabel *sectionLineLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, header.frame.size.height - 1, self.view.frame.size.width, 1)];
sectionLineLabel.backgroundColor = [UIColor blackColor];
[header addSubview:sectionLineLabel];
discloserImageView = [[UIImageView alloc] initWithFrame:CGRectMake(locationImageView.frame.size.width - 50, 0, 40, 40)];
discloserImageView.image = [UIImage imageNamed:#"down-arrow.png"];
discloserImageView.backgroundColor = [UIColor brownColor];
discloserImageView.tag = section;
[locationImageView addSubview:discloserImageView];
return header;
}
- (void)mTableView:(TQMultistageTableView *)mTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRow ----%ld",(long)indexPath.row);
}
#pragma mark - Header Open Or Close
- (void)mTableView:(TQMultistageTableView *)mTableView willOpenHeaderAtSection:(NSInteger)section
{
NSLog(#"Open Header ----%d",section);
// UITableViewHeaderFooterView *header = [self mTableView:mTableView viewForHeaderInSection:section];
UIView *headerView = [self mTableView:mTableView viewForHeaderInSection:section];
[[[headerView subviews] objectAtIndex:1] subviews];
NSLog(#"HeaderView :%#",headerView);
for (UIImageView *imageView in [[[headerView subviews] objectAtIndex:1] subviews]) {
if ([ imageView isKindOfClass:[UIImageView class]])
{
imageView.image = [UIImage imageNamed:#"up-arrow.png"];
}
}
}
In your code your header is not a UIImageView so your condition if ([header isKindOfClass:[UIImageView class]]) will never be true. Indeed, you add your UIImageView as a subview of a UIView.
What you can do instead is :
if ([[header subviews][0] isKindOfClass:[UIImageView class]])
{
UIImageView *imageViewChange =(UIImageView *) imageView;
imageViewChange.image = [UIImage imageName#"downArrow.png"];
}
Edit :
According to your edit, I think your best bet is to make your UIImageView a property as follows :
#interface YourViewController () {
UIImageView *imageViewChange;
}
and use it like that :
imageViewChange.image = [UIImage imageName#"downArrow.png"];

How to set property of UITextField at UITextField subclass

I have this subclass of UITextField and I would like to set a property as background color, border etc of UITextField. I don't know, if I use right method, because when I use this class for a UItextField, the UITextField doesn't change.. In which method I have to declare this properties?
#import "defaultUITextField.h"
#implementation defaultUITextField
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.delegate = self;
[self setBackgroundColor:([UIColor redColor])];
UIColor *borderColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:233.0/255.0];
self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
self.leftViewMode = UITextFieldViewModeAlways;
self.layer.borderColor = [borderColor CGColor];
self.layer.borderWidth = 1.0f;
}
return self;
}
#end
your solution seems to be right.
how did you place your suctom TextField on a View?
If you created your TextField in Interface Builder then you overrided the wrong constructor.
- (id)initWithCoder:(NSCoder *)inCoder {
if (self = [super initWithCoder:inCoder]) {
self.delegate = self;
[self setBackgroundColor:([UIColor redColor])];
UIColor *borderColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:233.0/255.0];
self.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
self.leftViewMode = UITextFieldViewModeAlways;
self.layer.borderColor = [borderColor CGColor];
self.layer.borderWidth = 1.0f;
}
return self;
}
this constructor is called when you create UITextField in IB and change its class to UItextField.

Adding UITapGestureRecognizer to UIScrollViews' UIView

I'm developing a Notification Center plugin, and I'm having trouble with UITapGestureRecognizer. I have a UIScrollView, With UIViews acting as a wrapper for my two UILabels in it.
The selector I attached to the UITapGestureRecognizer is never called, and I have no idea why.
EDIT: okay, now it works, but only for the last element in the UIScrollView. I guess it's because I'm using the same UILabel in the loop. What should I do?
- (UIView *)view
{
if (_view == nil)
{
self.aArray = [self.connector refreshData];
_view = [[UIView alloc] initWithFrame:CGRectMake(2, 0, 316, 110)];
//setting the background
UIImage *bg = [[UIImage imageWithContentsOfFile:#"/System/Library/WeeAppPlugins/NCAppline.bundle/WeeAppBackground.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:10];
UIImageView *bgView = [[UIImageView alloc] initWithImage:bg];
bgView.frame = CGRectMake(0, 0, 316, 110);
[_view addSubview:bgView];
//creating the scrollview
UIScrollView *scrView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
UITapGestureRecognizer *linkTappedRec = [[UITapGestureRecognizer alloc]
initWithTarget: self
action: #selector(articleTap:)];
linkTappedRec.numberOfTapsRequired = 1;
linkTappedRec.enabled = YES;
linkTappedRec.cancelsTouchesInView = YES;
//getting the number of pages required
NSInteger viewcount = [self.aArray count]/3;
for (int i = 0; i <viewcount; i++)
{
CGFloat y = i * self.view.frame.size.width;
UILabel *lbl1 = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 306, 23)];
/* setting bunch of properties */
UILabel *lbl2 = [[UILabel alloc] initWithFrame:CGRectMake(10, 25, 288, 85)];
/* setting bunch of properties */
//this will be the container
UIView *vview = [[UIView alloc] initWithFrame:CGRectMake(y, 0, self.view.frame.size.width, self.view.frame.size.height)];
[vview addSubview:lbl1];
[vview addSubview:lbl2];
vview.tag = i*3+2;
[vview addGestureRecognizer:linkTappedRec];
vview.userInteractionEnabled = YES;
[scrView addSubview:vview];
}
scrView.contentSize = CGSizeMake(self.view.frame.size.width *viewcount, self.view.frame.size.height);
scrView.pagingEnabled = YES;
[_view addSubview:scrView];
}
return _view;
}
- (void)articleTap:(UITapGestureRecognizer *)sender {
NSLog("tap");
}

No scrolling or user interaction in new NSWindow with NSScrollView

I am building an application (without interface builder!) which 'lives' in the NSStatusBar; when you click on an icon in the StatusBar a NSWindow with a NSScrollView appears. The window appears but it seems that something is preventing user interaction with the ScrollView
To find out where the problem comes from I also added my view to the main windows contentView in the AppDelegate, strange thing is that the scrollview is interactive in the MainWindow... Anyone knows why it doesn't work in my new Window?
This is the code I use to create the new TTDropDownWindow:
- (void)openWindow {
// Dropdown
if (self.dropDownWindow == nil) {
self.dropDownWindow = [[TTDropDownWindow alloc] init];
self.dropDownWindow.releasedWhenClosed = NO;
self.dropDownWindow.contentView = self.view;
self.dropDownWindow.backgroundColor = [NSColor clearColor];
self.dropDownWindow.delegate = self;
self.dropDownWindow.alphaValue = 1;
self.dropDownWindow.hasShadow = NO;
self.dropDownWindow.opaque = NO;
}
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSRect statusBarContentRect = self.statusBarItemView.window.frame;
NSPoint statusBarOriginPoint = NSMakePoint(NSMidX(statusBarContentRect), NSMinY(statusBarContentRect));
NSRect screenFrame = self.dropDownWindow.screen.frame;
NSRect dropDownContentRect = NSZeroRect;
dropDownContentRect.size.width = DROP_DOWN_WIDTH;
dropDownContentRect.size.height = DROP_DOWN_HEIGHT;
dropDownContentRect.origin.x = statusBarOriginPoint.x - DROP_DOWN_WIDTH / 2;
dropDownContentRect.origin.y = screenFrame.size.height - DROP_DOWN_HEIGHT - NSStatusBar.systemStatusBar.thickness;
[self.dropDownWindow setFrame:dropDownContentRect display:YES];
[self.dropDownWindow makeKeyAndOrderFront:nil];
}
This is the implementation of TTDropDownWindow:
#import "TTDropDownWindow.h"
#import "WFConstants.h"
#implementation TTDropDownWindow
- (id) init
{
self = [super initWithContentRect:NSMakeRect(0, 0, DROP_DOWN_WIDTH, DROP_DOWN_HEIGHT) styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:NO];
return self;
}
- (BOOL)canBecomeMainWindow {
return YES;
}
- (BOOL)canBecomeKeyWindow {
return YES;
}
#end
And this is the code that creates the View and the ScrollView
#import "TTStatusBarDropDownView.h"
#import "TTTestView.h"
#implementation TTStatusBarDropDownView
#synthesize dropDownTableViewData = dropDownTableViewData_;
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
NSImageView *imageView = [[NSImageView alloc] initWithFrame:frameRect];
imageView.image = [NSImage imageNamed:#"background-dropdown"];
[self addSubview:imageView];
// first create a view to put in a ScrollView
NSView *scrollViewHolder = [[TTTestView alloc] initWithFrame:NSMakeRect(19, 98, 414, 543) andColor:[NSColor yellowColor]];
[self addSubview:scrollViewHolder];
// create the scrollView
NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 414, 543)];
scrollView.hasVerticalRuler = YES;
scrollView.hasVerticalScroller = YES;
[scrollViewHolder addSubview:scrollView];
// TTTestView is just a NSView with a background drawing
TTTestView *theViewThatScrolls = [[TTTestView alloc] initWithFrame:NSMakeRect(0, 0, 200, 10000) andColor:[NSColor blueColor]];
[theViewThatScrolls addSubview:[[TTTestView alloc] initWithFrame:NSMakeRect(10, 10, 100, 8000) andColor:[NSColor grayColor]]];
[scrollView setDocumentView:theViewThatScrolls];
}
return self;
}
#end
You might change NSBackingStoreRetained to NSBackingStoreBuffered as stated over here:
NSScrollView in a NSWindow

Cocoa Touch: Creating and Adding Custom View

I create a custom view in cocoa touch that is superclassed by UIView and in my main controller I initialize it and then add it as a subview to the main view, but when I add it to the main view it calls my initializer method again and causes an infinite loop. Am I going about creating my custom view wrong?
Here is the mainView
- (void)loadView {
UIImage* tempImage = [UIImage imageNamed: #"image1.jpg"];
CustomImageContainer *testImage = [[CustomImageContainer alloc] initWithImage: tempImage andLabel: #"test image" onTop: true atX: 10 atY: 10];
[self.view addSubview: testImage];
}
and the CustomImageContainer
-(CustomImageContainer *) initWithImage: (UIImage *)imageToAdd andLabel: (NSString *)text onTop: (BOOL) top atX: (int) x_cord atY: (int) y_cord{
UIImageView *imageview_to_add = [[UIImageView alloc] initWithImage: imageToAdd];
imageview_to_add.frame = CGRectMake(0, 0, imageToAdd.size.width, imageToAdd.size.height);
UILabel *label_to_add = [[UILabel alloc] init];
label_to_add.text = text;
label_to_add.alpha = 50;
label_to_add.backgroundColor = [UIColor blackColor];
label_to_add.textColor = [UIColor whiteColor];
[self addSubview: imageview_to_add];
self.frame = CGRectMake(x_cord, y_cord, imageToAdd.size.width, imageToAdd.size.height);
if (top) {
label_to_add.frame = CGRectMake(0, 0, imageview_to_add.frame.size.width, imageview_to_add.frame.size.height);
//[self addSubview: label_to_add];
}
else {
label_to_add.frame = CGRectMake(0,.2 * imageview_to_add.frame.size.height, imageview_to_add.frame.size.width, imageview_to_add.frame.size.height);
}
[self addSubview: label_to_add];
[super init];
return self;
}
Why did you put the [super init] statement at the end of the initializer ? When subclassing, you usually put this statement at the start of method.
For UIView subclasses, the designated initializer when creating views in code is initWithFrame:, so you should call it before adding the label and the image. You can use the image to compute the frame needed by the custom view.
-(CustomImageContainer *) initWithImage: (UIImage *)imageToAdd andLabel: (NSString *)text onTop: (BOOL) top atX: (int) x_cord atY: (int) y_cord{
// The view will gets its frame to the size of the image
UIImageView *imageview_to_add = [[UIImageView alloc] initWithImage: imageToAdd];
// Call the designated initializer
CGRect frame = CGRectMake(x_cord, y_cord, imageToAdd.size.width, imageToAdd.size.height);
self = [super initWithFrame:frame];
[self addSubview: imageview_to_add];
UILabel *label_to_add = [[UILabel alloc] init];
label_to_add.text = text;
label_to_add.alpha = 50;
label_to_add.backgroundColor = [UIColor blackColor];
label_to_add.textColor = [UIColor whiteColor];
if (top) {
label_to_add.frame = CGRectMake(0, 0, imageview_to_add.frame.size.width, imageview_to_add.frame.size.height);
}
else {
label_to_add.frame = CGRectMake(0,.2 * imageview_to_add.frame.size.height, imageview_to_add.frame.size.width, imageview_to_add.frame.size.height);
}
[self addSubview: label_to_add];
return self;
}
If you still have an infinite loop, pause the debugger and search for the recurrent method pattern in the stack trace. This pattern will gives you where the code enters the infinite loop.