UILabel text from touchesbegan event - objective-c

By what method possible can I discover the text from a UILabel using the touchesBegan event?
The current code so far is...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
////
//insert code here to get currentLabel - not using viewYouWishToObtain.tag
////
NSLog(#"text: %#", currentLabel.text);
}
I wish I could simply write these... but these are all nefarious for different devious reasons
UILabel* currentLabel = [self.view hitTest:locationPoint withEvent:event];
NSLog(#"text: %#", currentLabel.text);
NSLog(#"text: %#",[self.view hitTest:locationPoint withEvent:event].text);
UILabel *newlabel = (UILabel*) event;
NSLog(#"text: %#", newlabel.text);
This is almost functionally equivalent code, but the general functionality is now dependent on NSDictionary.
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray* myword=[NSArray arrayWithObjects:#"h",#"e",#"l",#"l",#"o",nil];
NSDictionary *letterToNumber;
letterToNumber = [NSDictionary dictionaryWithObjectsAndKeys:
#"0", #"a",
#"1", #"b",
#"2", #"c",
#"3", #"d",
#"4", #"e",
#"5", #"f",
#"6", #"g",
#"7", #"h",
#"8", #"i",
#"9", #"j",
#"10", #"k",
#"11", #"l",
#"12", #"m",
#"13", #"n",
#"14", #"o",
#"15", #"p",
#"16", #"q",
#"17", #"r",
#"18", #"s",
#"19", #"t",
#"20", #"u",
#"21", #"v",
#"22", #"w",
#"23", #"x",
#"24", #"y",
#"25", #"z",
nil];
NSUInteger characterCount = [myword count];
for (int i=0;i<characterCount ;i++){
UILabel*myLabel;
myLabel=[[UILabel alloc] initWithFrame: CGRectMake((1+i)*35.0, 100.0, 30.0, 30.0)];
myLabel.backgroundColor = [UIColor whiteColor];
myLabel.text= [myword objectAtIndex:i];
myLabel.userInteractionEnabled = YES;
myLabel.tag=100+[[letterToNumber objectForKey:[myword objectAtIndex:i]] integerValue];
[self.view addSubview:myLabel];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
NSLog(#"1");
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
NSArray*myarray;
myarray = [NSArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",#"j",#"k",#"l",#"m",#"n",#"o",#"p",#"q",#"r",#"s",#"t",#"u",#"v",#"w",#"x",#"y",#"z",nil];
NSUInteger temp = viewYouWishToObtain.tag;
if (temp >= 100){
NSLog(#"text: %#",[myarray objectAtIndex:temp-100]);
}
if ([touch view] != viewYouWishToObtain && (viewYouWishToObtain.tag >= 100)) {
if ([touch tapCount] == 2) {
}
return;
}
}
Help with this coding problem would be great

Just out of curiosity, can you maybe switch from using UILabel's to just using UIButton's with the custom type. It should look just like a UILabel at that point and you can just wire up the touch event normally instead of needing a hittest. I think it would make things a lot easier for you.

UILabel * label = [[UILabel alloc] init];
UITapGestureRecognizer * tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelTapped:)];
[label addGestureRecognizer:tapGestureRecognizer];
Then use the labelTapped function to trace back the label and get the text ;)

Related

remove all NSTextField in NSVIew

I created NSView in XIB and then add dynamic muitple NSTextField, then add NSVIew to NSScrollView. But when I chane number of TextField, it is loop. I want to clear all old NStextfield before add new NSTextField. I had add clear function but it not work, my app hangs.
guiview refer to NSView (in XIB)
This is my code:
-(void) createTextDynamic : (int) number
{
for (NSView *subview in [guiView subviews]) { // function to clear all NStextfield but not work
[subview removeFromSuperview];
}
guiView = [[NSView alloc] init];
float heightView =(8*25 +50)+ (25+30) * number;
NSPoint pointToScrollTo = NSMakePoint( 400, 0); // Any point you like.
[[ScrollView contentView] scrollToPoint: pointToScrollTo];
[ScrollView reflectScrolledClipView: [ScrollView contentView]];
guiView.frame = NSMakeRect(0, 0, 400, heightView);
float label_Y = heightView - 25;
float textfield_Y = heightView - 25;
for(int i=1; i<=number;i++)
{
NSTextField *ssid = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
[ssid setStringValue:[NSString stringWithFormat:#"SSID %d :",i]];
[ssid setSelectable:NO];
[ssid setEditable:NO];
[ssid setBordered:NO];
[ssid setDrawsBackground:NO];
[ssid setAutoresizingMask:NSViewWidthSizable];
[guiView addSubview:ssid];
label_Y -=30;
[ssid release];
NSTextField *key = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
[key setStringValue:#"KEY :"];
[key setSelectable:NO];
[key setEditable:NO];
[key setBordered:NO];
[key setDrawsBackground:NO];
[key setAutoresizingMask:NSViewWidthSizable];
[guiView addSubview:key];
label_Y -=30;
[key release];
ssidtxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
[ssidtxt setBezelStyle:NSTextFieldSquareBezel];
ssidtxt.tag=i;
[ssidtxt setAutoresizingMask:NSViewWidthSizable];
[guiView addSubview:ssidtxt];
textfield_Y -=30;
[ssidtxt release];
keytxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
[keytxt setBezelStyle:NSTextFieldSquareBezel];
keytxt.tag=100+i;
[keytxt setAutoresizingMask:NSViewWidthSizable];
[guiView addSubview:keytxt];
textfield_Y -=30;
[keytxt release];
}
startLbl_Y = label_Y;
NSTextField *serverpath = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
[serverpath setStringValue:#"Server Path :"];
[serverpath setSelectable:NO];
[serverpath setEditable:NO];
[serverpath setBordered:NO];
[serverpath setDrawsBackground:NO];
[guiView addSubview:serverpath];
[serverpath release];
startText_Y = textfield_Y;
servertxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
[servertxt setBezelStyle:NSTextFieldSquareBezel];
[guiView addSubview:servertxt];
[servertxt release];
label_Y-=30;
NSTextField *username = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y ,150,25)];
[username setStringValue:#"User Name :"];
[username setSelectable:NO];
[username setEditable:NO];
[username setBordered:NO];
[username setDrawsBackground:NO];
[guiView addSubview:username];
[username release];
textfield_Y -=30;
usertxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
[usertxt setBezelStyle:NSTextFieldSquareBezel];
[guiView addSubview:usertxt];
[usertxt release];
label_Y-=30;
NSTextField *key = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
[key setStringValue:#"KEY :"];
[key setSelectable:NO];
[key setEditable:NO];
[key setBordered:NO];
[key setDrawsBackground:NO];
[guiView addSubview:key];
[key release];
textfield_Y -=30;
keytxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
[keytxt setBezelStyle:NSTextFieldSquareBezel];
[guiView addSubview:keytxt];
[keytxt release];
label_Y-=30;
NSTextField *buzz = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
[buzz setStringValue:#"Buzzer Mode :"];
[buzz setSelectable:NO];
[buzz setEditable:NO];
[buzz setBordered:NO];
[buzz setDrawsBackground:NO];
[guiView addSubview:buzz];
[buzz release];
textfield_Y -=60;
prototype= [[NSButtonCell alloc] init];
[prototype setTitle:#"Normal"];
[prototype setButtonType:NSRadioButton];
NSRect matrixRect = NSMakeRect(200, textfield_Y, 150, 50);
NSMatrix *myMatrix = [[NSMatrix alloc] initWithFrame:matrixRect
mode:NSRadioModeMatrix
prototype:(NSCell *)prototype
numberOfRows:2
numberOfColumns:1];
[myMatrix setAction:#selector(radioButtonClicked:)];
[myMatrix setTarget:self];
NSArray *cellArray = [myMatrix cells];
[[cellArray objectAtIndex:0] setTag:0];
[[cellArray objectAtIndex:1] setTitle:#"Mute"];
[[cellArray objectAtIndex:1] setTag:1];
[guiView addSubview:myMatrix];
[prototype release];
[myMatrix release];
[ScrollView setDocumentView :guiView];
}
Can you have any suggestions?
NSArray *viewsToRemove = [[guiView subviews] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSTextField class]];
}]];
[viewsToRemove makeObjectsPerformSelector:#selector(removeFromSuperview)];
By calling removeFromSuperview on a subview while looping through the superview's subviews, you're modifying -[NSView subviews] which you can't do.
But let's say that your code works. It looks like you're trying to remove all subviews (including the NSMatrix and not just the text fields). If you want to remove all subviews, then you can easily just call:
[[guiView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
If you're still looking for just the NSTextfield objects, then you can call either:
NSArray *viewsToRemove = [[guiView subviews] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSTextField class]];
}]];
[viewsToRemove makeObjectsPerformSelector:#selector(removeFromSuperview)];
Or the indexesOfObjectsPassingTest: approach (I think this one is faster than filteredArrayUsingPredicate: but I'm not entirely sure):
NSIndexSet *indexesToRemove = [[guiView subviews] indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [obj isKindOfClass:[NSTextField class]];
}];
NSArray *viewsToRemove = [[guiView subviews] objectsAtIndexes:indexesToRemove];
[viewsToRemove makeObjectsPerformSelector:#selector(removeFromSuperview)];
If you don't like selectors, then you can simply loop through the viewsToRemove array and call removeFromSuperview. Because you're looping through a different array than [guiView subviews], it should not crash or hang on that part.
I have never done it with OSX, but maybe something like the following?
NSArray *viewsToRemove = [guiView subviews];
for (NSView *v in viewsToRemove) {
if ([v isKindOfClass:[NSTextField class]]) {
[v removeFromSuperview];
}
}

add tap to focus functionality to ZBarReaderViewController

I am using the zbarsdk to read the barcodes . It is working fine , but my problem is I have added the overlay view to the ZBarReaderViewController (reader in my code ). So now I tried to add the tap to focus functionality . But it is crashing . Below is my code . Thanks in advance . Any ideas would be grateful .
-(IBAction)scanBarCode:(id)sender
{
barcodeClicked = 1;
NSLog(#"TBD: scan barcode here...");
// ADD: present a barcode reader that scans from the camera feed
reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
reader.showsZBarControls = NO;
UIView *ovlView = [[UIView alloc] init];
[ovlView setFrame:CGRectMake(0, 0, 320, 480)];
[ovlView setBackgroundColor:[UIColor clearColor]];
UIImageView *leftBracket = [[UIImageView alloc] init];
[leftBracket setFrame:CGRectMake(21, 100, 278, 15)];
[leftBracket setImage:[UIImage imageNamed:#"TopBracket.png"]];
UIImageView *rightBracket = [[UIImageView alloc] init];
[rightBracket setFrame:CGRectMake(21, 240, 278, 15)];
[rightBracket setImage:[UIImage imageNamed:#"BottomBracket.png"]];
UIToolbar *bottomBar = [[UIToolbar alloc] init];
[bottomBar setBarStyle:UIBarStyleBlackOpaque];
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height * [UIScreen mainScreen].scale >= 1136)
{
[bottomBar setFrame:CGRectMake(0, 524, 320, 44)];
}
else
[bottomBar setFrame:CGRectMake(0, 436, 320, 44)];
UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelCamera)];
/*UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];*/
//UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithTitle:#" Info " style:UIBarButtonItemStyleBordered target:self action:#selector(infoButton)];
/*UIButton *info = [UIButton buttonWithType:UIButtonTypeInfoLight];
[info addTarget:self action:#selector(infoButton) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithCustomView:info];
[bottomBar setItems:[NSArray arrayWithObjects:cancel,flexItem,infoButton, nil]];*/
[bottomBar setItems:[NSArray arrayWithObjects:cancel, nil]];
[ovlView addSubview:leftBracket];
[ovlView addSubview:rightBracket];
[ovlView addSubview:bottomBar];
reader.cameraOverlayView = ovlView;
// present and release the controller
[self presentModalViewController:reader
animated: YES];
[reader release];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UIView * previewView = [[[[[[[[[[
reader.view // UILayoutContainerView
subviews] objectAtIndex:0] // UINavigationTransitionView
subviews] objectAtIndex:0] // UIViewControllerWrapperView
subviews] objectAtIndex:0] // UIView
subviews] objectAtIndex:0] // PLCameraView
subviews] objectAtIndex:0]; // PLPreviewView
[previewView touchesBegan:touches withEvent:event];
}
Thanks for MacN00b's answer! That points out the right direction to go for me. I have implemented tap-focus for zbarViewController. Here is the idea:
You can add a custom view to zbarViewController by assigning a custom view to its cameraOverlayView. Then add a TapGestureRecagonizer to the custom view to catch the tap. Then, get the touch point and make the camera focus to the touch point. You would like possibly add a little rectangle around the touch point(that is what I did).
Here goes the code(assigning the custom view to cameraOverlayView:
UIView *view = [[UIView alloc] init];
UITapGestureRecognizer* tapScanner = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(focusAtPoint:)];
[view addGestureRecognizer:tapScanner];
reader.cameraOverlayView = view;
Then in selector focusAtPoint:
- (void)focusAtPoint:(id) sender{
CGPoint touchPoint = [(UITapGestureRecognizer*)sender locationInView:_reader.cameraOverlayView];
double focus_x = touchPoint.x/_reader.cameraOverlayView.frame.size.width;
double focus_y = (touchPoint.y+66)/_reader.cameraOverlayView.frame.size.height;
NSError *error;
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices){
NSLog(#"Device name: %#", [device localizedName]);
if ([device hasMediaType:AVMediaTypeVideo]) {
if ([device position] == AVCaptureDevicePositionBack) {
NSLog(#"Device position : back");
CGPoint point = CGPointMake(focus_y, 1-focus_x);
if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device lockForConfiguration:&error]){
[device setFocusPointOfInterest:point];
CGRect rect = CGRectMake(touchPoint.x-30, touchPoint.y-30, 60, 60);
UIView *focusRect = [[UIView alloc] initWithFrame:rect];
focusRect.layer.borderColor = [UIColor whiteColor].CGColor;
focusRect.layer.borderWidth = 2;
focusRect.tag = 99;
[_reader.cameraOverlayView addSubview:focusRect];
[NSTimer scheduledTimerWithTimeInterval: 1
target: self
selector: #selector(dismissFocusRect)
userInfo: nil
repeats: NO];
[device setFocusMode:AVCaptureFocusModeAutoFocus];
[device unlockForConfiguration];
}
}
}
}
}
I have added a white rectangle around the touch point, and then use selector dismissFocusRect to dismiss this rectangle. Here is the code:
- (void) dismissFocusRect{
for (UIView *subView in _reader.cameraOverlayView.subviews)
{
if (subView.tag == 99)
{
[subView removeFromSuperview];
}
}
}
I hope this could help!
Look at this documentation by apple in the "Focus Modes" section: https://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html It talks all about how to implement tap to focus properly. I would try to implement this by
CGRect screenRect = [[UIScreen mainScreen] bounds];
screenWidth = screenRect.size.width;
screenHeight = screenRect.size.height;
double focus_x = thisFocusPoint.center.x/screenWidth;
double focus_y = thisFocusPoint.center.y/screenHeight;
[[self captureManager].videoDevice lockForConfiguration:&error];
[[self captureManager].videoDevice setFocusPointOfInterest:CGPointMake(focus_x,focus_y)];
Well if you are using that view controller, how about adding a (void) that should be ok to implement in the barcodeviewcontroller.
- (void) focusAtPoint:(CGPoint)point
{
AVCaptureDevice *device = [[self videoInput] device];
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeAutoFocus];
[device unlockForConfiguration];
} else {
id delegate = [self delegate];
if ([delegate respondsToSelector:#selector(acquiringDeviceLockFailedWithError:)]) {
[delegate acquiringDeviceLockFailedWithError:error];
}
}
}
}

How can I get equivalent functionality across all iterations of a programmatically created series of UILabel objects

Advaced Question: How can I get equivalent functionality across all iterations of a programmatically created series of UILabel objects in UIView (to function across CGIntersect with a second series of UILabels)?
Can all instances of a programmatically created UILabel series possess the equivalent title (self.MYUILABEL) and retain equivalent functionality?
I made a series of equivalently classed UILabels programmatically with a for loop, but only the last made instance of UILabel is assigned the UILabel title.
How can I get equivalent functionality across all iterations of a programmatically created series of UILabel objects in UIView?
The goal is to get one series of UILabels to be moved by touch to a second series of UILabels.
Here is how I made the UILabels (which act as goal zones) in my view.
for (int i=0;i<characterCount ;i++){
self.myBottomLabel=[[UILabel alloc] initWithFrame: CGRectMake((i*60.0)+10, 200.0, 50.0, 50.0)];
self.myBottomLabel.backgroundColor = [UIColor whiteColor];
self.myBottomLabel.text= [myword objectAtIndex:i];
self.myBottomLabel.userInteractionEnabled = NO;
self.myBottomLabel.tag=300+[[letterToNumber objectForKey:[myword objectAtIndex:i]] integerValue];
[self.view insertSubview: self.myBottomLabel atIndex:(500)];
}
When I attempt to use CGRectIntersectsRect using self.myBottomLabel only the last UILabel made will function correctly with the self.myBottomLabel title used by thisCGRect:
theReceivingCard = [self.myBottomLabel convertRect:[self.myBottomLabel frame] toView:self.view];
Here is almost all of the implementation. Do I need to create multiple CGRects (Which I don't know how to do)? Or is there someway to find exactly what the tag is of these UILabel (which are made interactive when you move a corresponding UILabel over the top of them?)
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray* myword=[NSArray arrayWithObjects:#"h",#"e",#"l",#"l",#"o",nil];
NSDictionary *letterToNumber;
letterToNumber = [NSDictionary dictionaryWithObjectsAndKeys:
#"0", #"a",
#"1", #"b",
#"2", #"c",
#"3", #"d",
#"4", #"e",
#"5", #"f",
#"6", #"g",
#"7", #"h",
#"8", #"i",
#"9", #"j",
#"10", #"k",
#"11", #"l",
#"12", #"m",
#"13", #"n",
#"14", #"o",
#"15", #"p",
#"16", #"q",
#"17", #"r",
#"18", #"s",
#"19", #"t",
#"20", #"u",
#"21", #"v",
#"22", #"w",
#"23", #"x",
#"24", #"y",
#"25", #"z",
nil];
NSUInteger characterCount = [myword count];
//moveable
for (int i=0;i<characterCount ;i++){
self.myTopLabel=[[UILabel alloc] initWithFrame: CGRectMake((i*60.0)+10, 100.0, 50.0, 50.0)];
self.myTopLabel.backgroundColor = [UIColor whiteColor];
self.myTopLabel.text= [myword objectAtIndex:i];
self.myTopLabel.userInteractionEnabled = YES;
self.myTopLabel.tag=100+[[letterToNumber objectForKey:[myword objectAtIndex:i]] integerValue];
[self.view insertSubview: self.myTopLabel atIndex:(1)];
}
//receiver
for (int i=0;i<characterCount ;i++){
self.myBottomLabel=[[UILabel alloc] initWithFrame: CGRectMake((i*60.0)+10, 200.0, 50.0, 50.0)];
self.myBottomLabel.backgroundColor = [UIColor whiteColor];
self.myBottomLabel.text= [myword objectAtIndex:i];
self.myBottomLabel.userInteractionEnabled = NO;
self.myBottomLabel.tag=300+[[letterToNumber objectForKey:[myword objectAtIndex:i]] integerValue];
[self.view insertSubview: self.myBottomLabel atIndex:(500)];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
[[viewYouWishToObtain superview] bringSubviewToFront:viewYouWishToObtain];
if ([touch view] != viewYouWishToObtain && viewYouWishToObtain.tag >= 100 && viewYouWishToObtain.tag <= 200) {
if ([touch tapCount] == 2) {
}
return;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
if ([touch view] == viewYouWishToObtain && viewYouWishToObtain.tag >= 100 && viewYouWishToObtain.tag <= 200) {
CGPoint location = [touch locationInView:self.view];
viewYouWishToObtain.center = location;
theMovingCard = [viewYouWishToObtain convertRect:[viewYouWishToObtain frame] toView:self.view];
theReceivingCard = [self.myBottomLabel convertRect:[self.myBottomLabel frame] toView:self.view];
CGRect theZone = CGRectMake(theReceivingCard.origin.x, theReceivingCard.origin.y,theReceivingCard.size.width*2 , theReceivingCard.size.height*2);
CGRect theCard = CGRectMake(theMovingCard.origin.x, theMovingCard.origin.y,theMovingCard.size.width*2 , theMovingCard.size.height*2);
if(CGRectIntersectsRect(theCard, theZone))
{
NSLog(#"intersect");
}
return;
}
}
The problem is that right there at the end of all the code, the intersect only functions on the last made UILabel. I need the intersect to work across all of the series of UILabels that act as receivers. Super super super super thanks in advance.
You're making a ton of labels in your loop but you only have a pointer to the last one you created, since you assign them all to the same property. I'm not totally clear on the rest of your question but I think you should be adding those labels to an array, and iterating through that array when you are hit testing etc.
Here is the answer of "how to programmatically create multiple CGRect values for multiple CGIntersects for UIView subset matching" by iteration through a for loop.
This is the complete file.
It is an iOS touch enabled foundation for a card game (like solitaire) or as match game (children's education).
The program makes 10 cards where the top row has to match the bottom row. If the top row card has text equivalent to the bottom row card then the CGIntersect will 'hit' and you can execute any additional methods.
There should be a simpler way to make variable CGRect, but I can't find the answer. If someone can figure out how to NOT use a NSMutableArray and a for-loop to generate the CGrect code, then I would be greatly obliged if you would share.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property NSString* currentCard;
#property NSArray* myWord;
#property NSString* myCurrentLetter;
#property NSMutableArray* myMoverMutableArray;
#property NSMutableArray* myReceiverMutableArray;
#end
.m
#import "ViewController.h"
#interface ViewController ()
{
int myLetterTagNumber;
}
#end
#implementation ViewController
#synthesize currentCard = _currentCard;
#synthesize myWord = _myWord;
#synthesize myCurrentLetter = _myCurrentLetter;
#synthesize myMoverMutableArray = _myMoverMutableArray;
#synthesize myReceiverMutableArray = _myReceiverMutableArray;
- (void)viewDidLoad
{
[super viewDidLoad];
[self writer];
}
-(void)writer{
self.myWord=[NSArray arrayWithObjects:#"l",#"i",#"l",#"l",#"y",nil];
NSUInteger characterCount = [self.myWord count];
self.myMoverMutableArray = [NSMutableArray arrayWithCapacity:characterCount];
self.myReceiverMutableArray = [NSMutableArray arrayWithCapacity:characterCount];
//moveable
for (int i=0;i<characterCount ;i++){
UILabel*myTopLabel;
myTopLabel=[[UILabel alloc] initWithFrame: CGRectMake((i*60.0)+10, 100.0, 50.0, 50.0)];
myTopLabel.backgroundColor = [UIColor whiteColor];
myTopLabel.text= [self.myWord objectAtIndex:i];
myTopLabel.userInteractionEnabled = YES;
myTopLabel.textAlignment = UITextAlignmentCenter;
myTopLabel.tag=100+i;
[self.myMoverMutableArray addObject:[self.myWord objectAtIndex:i]];
[self.view insertSubview: myTopLabel atIndex:(100)];
}
//receiver
for (int i=0;i<characterCount ;i++){
UILabel*myBottomLabel;
myBottomLabel=[[UILabel alloc] initWithFrame: CGRectMake((i*60.0)+10, 200.0, 50.0, 50.0)];
myBottomLabel.backgroundColor = [UIColor redColor];
myBottomLabel.text= [self.myWord objectAtIndex:i];
myBottomLabel.userInteractionEnabled = YES;
myBottomLabel.textAlignment = UITextAlignmentCenter;
myBottomLabel.tag=300+i;
[self.myReceiverMutableArray addObject:[self.myWord objectAtIndex:i]];
[self.view insertSubview: myBottomLabel atIndex:(300)];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
//clipping
[[viewYouWishToObtain superview] bringSubviewToFront:viewYouWishToObtain];
myLetterTagNumber = viewYouWishToObtain.tag;
UILabel * myTempUILabel = (UILabel*)[self.view viewWithTag:(myLetterTagNumber)];
self.myCurrentLetter = myTempUILabel.text;
NSLog (#"text: %#",myTempUILabel.text);
NSLog (#"Tag: %d",myLetterTagNumber);
if ([touch view] != viewYouWishToObtain && viewYouWishToObtain.tag >= 100 && viewYouWishToObtain.tag <= 200) {
if ([touch tapCount] == 2) {
}
return;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
if ([touch view] == viewYouWishToObtain && viewYouWishToObtain.tag >= 100 && viewYouWishToObtain.tag <= 200) {
CGPoint location = [touch locationInView:self.view];
viewYouWishToObtain.center = location;
//moving card rec
CGRect theMovingCard;
theMovingCard = [viewYouWishToObtain convertRect:[viewYouWishToObtain frame] toView:self.view];
CGRect themovingRect = CGRectMake(theMovingCard.origin.x, theMovingCard.origin.y,theMovingCard.size.width*2 , theMovingCard.size.height*2);
NSString *myTempString;
NSUInteger characterCount = [self.myWord count];
for (int i=0;i<characterCount ;i++){
myTempString= [self.myReceiverMutableArray objectAtIndex:i];
if (myTempString == self.myCurrentLetter){
UILabel * mytouchMoveUILabel = (UILabel*)[self.view viewWithTag:(i+300)];
CGRect theReceivingCard;
theReceivingCard = [mytouchMoveUILabel convertRect:[mytouchMoveUILabel frame] toView:self.view];
CGRect spaceToHitRect = CGRectMake(theReceivingCard.origin.x, theReceivingCard.origin.y,theReceivingCard.size.width*2 , theReceivingCard.size.height*2);
if(CGRectIntersectsRect(themovingRect, spaceToHitRect))
{
NSLog (#"Intersect: %d",myLetterTagNumber);
}
}//if
}//for
return;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
// NSLog(#"3");
CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
UIView* viewYouWishToObtain = [self.view hitTest:locationPoint withEvent:event];
if ([touch view] == viewYouWishToObtain && viewYouWishToObtain.tag >= 100 && viewYouWishToObtain.tag <= 200) {
return;
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end

How to animate the NSSplitView while resizing?

I would like to animate while resizing NSSplitView programatically.
Here is the code for resizing the view in SplitView
In awakeFromNib: Iam observing the NSSplitViewWillResizeSubviewsNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(splitViewWillResizeSubviewsHandler:)
name:NSSplitViewWillResizeSubviewsNotification
object:splitView];
SplitView Resize
NSView * leftSubView = [[splitView subviews] objectAtIndex:0];
if ([leftSubView isHidden])
{
[leftSubView setHidden:NO];
[splitView setPosition:0 ofDividerAtIndex:0];
}
else
{
[leftSubView setHidden:YES];
}
[splitView adjustSubviews];
[[NSNotificationCenter defaultCenter] postNotificationName:NSSplitViewWillResizeSubviewsNotification object:self userInfo:nil];
I am able to resize the splitView.Where should I add the animationCode.(As rightView moves to replace the leftSubView, I want the resize happen with some delay) ?
I have the rects of the two Views before and after the resize.Where should I write the animation Code.
Iam able to solve the animations. Following Code works for me
-(IBAction)resizeViews:(id)sender
{
NSSplitView *splitView = [self splitView];
NSView * leftSubView = [[splitView subviews] objectAtIndex:0];
NSView * rightSubView = [[splitView subviews] objectAtIndex:1];
NSLog(#"splitView Frame %#",NSStringFromRect(splitView.frame));
NSLog(#"left Frame %#",NSStringFromRect(leftSubView.frame));
NSLog(#"right Frame %#",NSStringFromRect(rightSubView.frame));
self.lastLeftViewWidth = leftSubView.frame.size.width;
NSMutableDictionary *collapseMainAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
[collapseMainAnimationDict setObject:rightSubView forKey:NSViewAnimationTargetKey];
NSRect newRightSubViewFrame = rightSubView.frame;
newRightSubViewFrame.size.width = splitView.frame.size.width;
[collapseMainAnimationDict setObject:[NSValue valueWithRect:newRightSubViewFrame] forKey:NSViewAnimationEndFrameKey];
NSMutableDictionary *collapseInspectorAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
[collapseInspectorAnimationDict setObject:leftSubView forKey:NSViewAnimationTargetKey];
NSRect newLeftSubViewFrame = leftSubView.frame;
newLeftSubViewFrame.size.width = 0.0f;
newLeftSubViewFrame.origin.x = splitView.frame.size.width;
[collapseInspectorAnimationDict setObject:[NSValue valueWithRect:newLeftSubViewFrame] forKey:NSViewAnimationEndFrameKey];
NSViewAnimation *collapseAnimation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:collapseMainAnimationDict, collapseInspectorAnimationDict, nil]];
[collapseAnimation setDuration:0.60f];
[collapseAnimation startAnimation];
[splitView adjustSubviews];
[splitView setNeedsDisplay:YES];
}
-(IBAction)normalizeViews:(id)sender
{
NSView * left = [[self.splitView subviews] objectAtIndex:0];
NSView * right = [[self.splitView subviews] objectAtIndex:1];
NSLog(#"splitView Frame %#",NSStringFromRect( self.splitView.frame));
NSLog(#"left Frame %#",NSStringFromRect( left.frame));
NSLog(#"right Frame %#",NSStringFromRect( right.frame));
// [right setFrame: NSMakeRect(0, right.frame.origin.y, right.frame.size.width-118, right.frame.size.height)];
// [left setFrame:NSMakeRect(0, 0, 118, left.frame.size.height)];
left.hidden = NO;
NSMutableDictionary *expandMainAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
[expandMainAnimationDict setObject:right forKey:NSViewAnimationTargetKey];
NSRect newMainFrame = right.frame;
newMainFrame.size.width = self.splitView.frame.size.width-self.lastLeftViewWidth;
[expandMainAnimationDict setObject:[NSValue valueWithRect:newMainFrame] forKey:NSViewAnimationEndFrameKey];
NSMutableDictionary *expandInspectorAnimationDict = [NSMutableDictionary dictionaryWithCapacity:2];
[expandInspectorAnimationDict setObject:left forKey:NSViewAnimationTargetKey];
NSRect newInspectorFrame = left.frame;
newInspectorFrame.size.width = self.lastLeftViewWidth;
newInspectorFrame.origin.x = self.splitView.frame.size.width-self.lastLeftViewWidth;
[expandInspectorAnimationDict setObject:[NSValue valueWithRect:newInspectorFrame] forKey:NSViewAnimationEndFrameKey];
NSViewAnimation *expandAnimation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:expandMainAnimationDict, expandInspectorAnimationDict, nil]];
[expandAnimation setDuration:0.60f];
[expandAnimation startAnimation];
[self.splitView adjustSubviews];
[self.splitView setNeedsDisplay:YES];
}
Following Link helped me in solving the issue
How to expand and collapse NSSplitView subviews with animation?

Eraser for UIBezierPath

I am using UIBezierPath for free hand drawing in an iPad app. I want to apply an eraser to a uibezierpath.
However, I want to only erase the drawing in its path. I cannot use the path color as the background color because I have other elements on the background.
Below is how I am creating my free hand drawings:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
lineWidths = 10;
brushPattern = [UIColor greenColor];
pathArray = [[NSMutableArray alloc]init];
bufferArray = [[NSMutableArray alloc]init];
self.multipleTouchEnabled = NO;
}
return self;
}
- (void)drawRect:(CGRect)rect {
for (NSMutableDictionary *dictionary in pathArray) {
UIBezierPath *_path = [dictionary objectForKey:#"Path"];
UIColor *_colors = [dictionary objectForKey:#"Colors"];
[_colors setStroke];
_path.lineCapStyle = kCGLineCapRound;
[_path stroke];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
myPath = [[UIBezierPath alloc]init];
myPath.lineWidth = lineWidths;
CGPoint touchPoint = [[touches anyObject] locationInView:self];
UITouch *mytouch = [[touches allObjects] objectAtIndex:0];
[myPath moveToPoint:[mytouch locationInView:self]];
[myPath addLineToPoint:CGPointMake(touchPoint.x, touchPoint.y)];
dict = #{#"Path": myPath, #"Colors": brushPattern};
[pathArray addObject:dict];
[self setNeedsDisplay];
[undoManager registerUndoWithTarget:self selector:#selector(undoButtonClicked) object:nil];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *mytouch = [[touches allObjects] objectAtIndex:0];
[myPath addLineToPoint:[mytouch locationInView:self]];
[self setNeedsDisplay];
}
Store a BOOL value for erase: BOOL _erase;
BOOL eraseButtonIsTapped = ...
if eraseButtonIsTapped {
_erase = yes;
} else{
_erase = NO;
}
When drawing:
[myPath strokeWithBlendMode:_erase?kCGBlendModeClear:kCGBlendModeNormal alpha:1.0f];
Just try this
brushPattern = view.backgroundColor;
This will draw a new line with the color what exactly behind your drawn path. And you can use the same pathArray to do this. So that later on you can implement redo/undo operations too. if you want i could explain you more on this.