multitouch and buttons in same view - objective-c

hi I have an app UIViewController that supports multitouch and has some buttons too, what i need is that when user double click on button it opens a new view, and when the user move is finger on screen it opens other view.
The app works fine if user put his finger in the area where there is no button, but if he puts his fingers in the area where there are buttons nothing happens
- (void)viewDidLoad
{
[super viewDidLoad];
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(openPic:)
forControlEvents:UIControlEventTouchDownRepeat];
button.tag = image;
button.frame = CGRectMake(orInc, inc, 70.0, 95.0);
[self.view addSubview:button];
]
-(void) openPic:(id)sender {
UINavigationController *nav=[[UINavigationController alloc]init];
PicController *x=[[PicController alloc]init];
nav.viewControllers=[NSArray arrayWithObject:x];
[self.navigationController pushViewController:x animated:YES];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UINavigationController *nav=[[UINavigationController alloc]init];
ViewController *x=[[ViewController alloc]init];
nav.viewControllers=[NSArray arrayWithObject:x];
[self.navigationController pushViewController:x animated:YES];
}

Set userInteractionEnabled property of he UIButton object to NO and try it.

Related

UIPopoverPresentationController can not be dismissed on iPhone

I'm implementing a CABTMIDICentralViewController (Apple's pre-fab BTLE MIDI configuration panel). The code below is Apple's sample code - unmodified.
It works perfectly on iPad, but on iPhone/iPod it results in an uncloseable fullscreen view. The code clearly creates a Done button, but it isn't shown on the devices.
The common answer is "you need a UINavigationController", but there is one being made in this code. So I'm not sure what else is missing?
- (void)doneAction:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)configureCentral:(id)sender
{
CABTMIDICentralViewController *viewController [CABTMIDICentralViewController new];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
// this will present a view controller as a popover in iPad and modal VC on iPhone
viewController.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneAction:)];
navController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popC = navController.popoverPresentationController;
popC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popC.sourceRect = [sender frame];
UIButton *button = (UIButton *)sender;
popC.sourceView = button.superview;
[self presentViewController:navController animated:YES completion:nil];
}
You will have to implement the UIPopoverPresentationControllerDelegate to view popovers in iPhones. By default it will be presented in the style of an already presented view controller.
Add this piece of code to present the controller as popover
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(nonnull UITraitCollection *)traitCollection {
return UIModalPresentationNone;
}

Why does my textField disappear?

I do some practice with iPhone4S about UITextField on iOS 7.1.2.
Interface:
The interface of the first version is simple, which just has a custom UITextField named MyUITextField and a UIButtom object that use to cancel the search operation. Inside the textField, its leftView property is initially set to a UIButton object, which background image is a magnifying glass. When users tap in the textField, that magnifying glass button will be removed and the leftView property will also set to a new UIButton object, which background image is a inverted triangle. When users tap the triangle button, app will create a new view object.
Main code:
//In this version,the textField's original frame property is set to (10,40,250,30)
//and the main operations are like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTextField.delegate = self;
self.myTextField.leftViewMode = UITextFieldViewModeUnlessEditing;
self.myTextField.leftView = [self creCustomSearchBar];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyBoardWillAppear:)
name:#"UIKeyboardWillShowNotification"
object:nil];
[self.cancleSearchButton addTarget:self
action:#selector(cancleSearch:)
forControlEvents:UIControlEventTouchUpInside];
}
/*when tapping in the textField,keyboard will appear*/
- (void)keyBoardWillAppear:(NSNotification *)notification
{
CGRect newLeftViewIndicatorRect = CGRectMake(20,5,20,20);
UIButton *newLeftViewIndicator = [[UIButton alloc] initWithFrame:newLeftViewIndicatorRect];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"searchbar_textfield_down_icon#2x" ofType:#"png"];
[newLeftViewIndicator setBackgroundImage:[UIImage imageWithContentsOfFile:imagePath] forState:UIControlStateNormal];
[newLeftViewIndicator addTarget:self action:#selector(createActuralLeftView:) forControlEvents:UIControlEventTouchUpInside];
self.myTextField.leftView = newLeftViewIndicator;
/*in the second verson need to call */
//[self adjustViewFrame];
[self.cancleSearchButton setTitle:#"取消" forState:UIControlStateNormal];
}
- (void)createActuralLeftView:(UIButton *)leftViewButton
{
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(tapRegionAboveKeyboard:)];
[self.view addGestureRecognizer:tapGesture];
NewLeftView *leftView = [[NewLeftView alloc] initWithFrame:CGRectMake(10, 80, 140, 100)];
leftView.delegate = self;
[self.view addSubview:leftView];
}
- (void)tapRegionAboveKeyboard:(UITapGestureRecognizer *)tapGesture
{
for (UIView *v in self.view.subviews) {
if ([v isKindOfClass:[NewLeftView class]]) {
[v removeFromSuperview];
[self.view removeGestureRecognizer:tapGesture];
return;
}
}
}
//in the second version need to call
- (void)adjustViewFrame
{
[[self.myTextField class] animateWithDuration:0.05 animations:^{
[self.myTextField setFrame:CGRectMake(self.myTextField.frame.origin.x, 40, self.myTextField.frame.size.width, self.myTextField.frame.size.height)];
}];
[[self.cancleSearchButton class] animateWithDuration:0.05 animations:^{
[self.cancleSearchButton setFrame:CGRectMake(self.cancleSearchButton.frame.origin.x, 40, self.cancleSearchButton.frame.size.width, self.cancleSearchButton.bounds.size.height)];
}];
}
In the first version things work well.
But in the second version, I set the textField frame property to (10,260,250,30), so I need to call the adjustViewFrame method in the keyBoardWillAppear: to reposition the textField in case of obscuring by the keyboard.
Here comes the problem: the textField's position is correctly moved to the right place, but when I tap the inverted triangle button, the textField disappeared.
I can't figure out what's going wrong here.

Display default tabBarView on tabBarItem Click event

I have used UITabbarController in my app.One of the tabBarItem is contactsViewController which displays list of contacts with UITableView.When I click on the tableRow it loads another view.then I click some other tabBarItem.again I click contactsViewController it takes me to the view where i left.It does not display default contact view.I have created UITabbarController progrmattically.How do i display default tabBarView on tabBarItem click?
tabbarController = [[UITabBarController alloc]init];
self.tabbarController.delegate = self;
tabbarView = [[UIView alloc]initWithFrame:CGRectMake(0, 431, 320, 49)];
UIImageView *tabImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 49)];
[tabImage setImage:[UIImage imageNamed:#"Taskbar.png"]];
[tabbarView addSubview:tabImage];
UIButton *tabItem1 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 64, 49)];
[tabItem1 setImage:[UIImage imageNamed:#"Btn_Home.png"] forState:UIControlStateNormal];
[tabItem1 setTag:1];
[tabItem1 addTarget:self action:#selector(tabBarBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[tabbarView addSubview:tabItem1];
-(IBAction)tabBarBtnAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
// NSLog(#"tag %d\n",btn.tag);
[self resetTabBarBtnImage];
[self resetAllTabBarBtnImage];
PreviousBtnTag = btn.tag;
if ([btn tag]==1) {
tabbarView.hidden = YES;
[self.tabbarController setSelectedIndex:0];
[self.navigationController popToRootViewControllerAnimated:YES];
[btn setImage:[UIImage imageNamed:#"Btn_Home-Over.png"] forState:UIControlStateNormal];
}
else if([btn tag]==2)
{
tabbarView.hidden = NO;
[self.tabbarController setSelectedIndex:1];
[btn setImage:[UIImage imageNamed:#"Btn_Contacts-Over.png"] forState:UIControlStateNormal];
[self.navigationController popToRootViewControllerAnimated:YES];
}
In the appDelegate class , initially set the UItabbarController delegate as self
In the implememtation of appDelegate i.e .m file
//Assuming the first tab has the contactsviewController
-
(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (tabBarController.selectedIndex == 0) {
UINavigationController *requiredNavigationController = [tabBarController.viewControllers objectAtIndex:0];
[requiredNavigationController popToRootViewControllerAnimated:YES];
}
}
I would recommend you to create the "tab bar controller" with the Interface Builder, as it is much easier to implement these kind of things this way. Anyway, if you want to keep trying to create it programmatically, try changing this:
[self.navigationController popToRootViewControllerAnimated:YES];
for this:
RootViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"Root"];
[self.navigationController pushViewController:controller animated:YES];
If this does not work for you, why don't you use Tool Bar Items, in instead of a Tab Bar Controller? It is quite easy to manage events with Tool Bar items, as they are treated like buttons.
Good luck!

UIBarButtonItem and UIGestureRecognizer

I have a UIView where i added a UITapGestureRecognizer:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
tapRecognizer.numberOfTapsRequired=1;
tapRecognizer.numberOfTouchesRequired=1;
[self.myView addGestureRecognizer:tapRecognizer];
I then add a UIToolBar with a button to the view:
UIToolbar *topBar = [[UIToolbar alloc ]initWithFrame:CGRectMake(0, 0, self.myView.frame.size.width, 44)];
topBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *logout = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStyleBordered target:self action:#selector(logout)];
[topBar setItems:#[logout] animated:NO];
I'm having an issue where I click on the logout button, and my tap recognier fires instead of my logout action. If I click and hold, then the logout action will fire (I'm guessing the tap recognizer is failing so lets the buttion action fire).
how can I not fire the gesture recognizer when the button is pressed?
Just had the same problem. Because I don't want to introduce container views (the UIToolbar should cover my existing view). With the help of Patrick.Ji's coarsely pointing I came up with this:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view.superview isKindOfClass:[UIToolbar class]]) {
return NO;
}
return YES;
}
Don't forget to set the delegate of the gesture to self
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *mainTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(mainTapGesture:)];
mainTapGestureRecognizer.delegate = self;
[self.view addGestureRecognizer:mainTapGestureRecognizer];
}
Check the view in your tap recognizer. If it is your logout button, let the touch fail to pass it up the chain via super.
Alternatively, make sure your toolbar is not a subview of your view. Instead, have a container view containing with your toolbar and your content view, and add the gesture recognizer to this content view.
implement this delegate method of UIGestureRecognizer (remember to set your tapRecognizer.delegate = self)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch: (UITouch *)touch {
if ([touch.view isKindOfClass:[UIBarButtonItem class]])
{
return NO;
}
return YES;
}

UIView in front of everything not rotating with screen?

I have this code:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:#"image.png"];
UIApplication *app = [UIApplication sharedApplication];
[app addSubViewOnFrontWindow:imageView];
...
- (void)addSubViewOnFrontWindow:(UIView *)view {
int count = [self.windows count];
UIWindow *w = [self.windows objectAtIndex:count - 1];
[w addSubview:view];
}
The problem is, when the app rotates, the view on the front doesn't rotate. It just stays in portrait.
How can I get this to rotate normally with the rest of the device?
I haven't tried this, but UIWindow has a property rootViewController
The root view controller for the window.
#property(nonatomic, retain) UIViewController *rootViewController
Discussion
The root view controller provides the content view of the
window. Assigning a view controller to this property (either
programmatically or using Interface Builder) installs the view
controller’s view as the content view of the window. If the window has
an existing view hierarchy, the old views are removed before the new
ones are installed.
The default value of this property is nil.
Availability
Available in iOS 4.0 and later.
Declared In
UIWindow.h
As you should be providing this root view controller you should be able to add it to the rootViewContoller's view, and handle aout rotation correctly.
another solution could be, that you swap the windo with a custom one while presenting your view, with another view controller. this trick in action you can see in the implementation of TSAlertView.
- (void) show
{
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
TSAlertViewController* avc = [[[TSAlertViewController alloc] init] autorelease];
avc.view.backgroundColor = [UIColor clearColor];
// $important - the window is released only when the user clicks an alert view button
TSAlertOverlayWindow* ow = [[TSAlertOverlayWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
ow.alpha = 0.0;
ow.backgroundColor = [UIColor clearColor];
ow.rootViewController = avc;
[ow makeKeyAndVisible];
// fade in the window
[UIView animateWithDuration: 0.2 animations: ^{
ow.alpha = 1;
}];
// add and pulse the alertview
// add the alertview
[avc.view addSubview: self];
[self sizeToFit];
self.center = CGPointMake( CGRectGetMidX( avc.view.bounds ), CGRectGetMidY( avc.view.bounds ) );;
self.frame = CGRectIntegral( self.frame );
[self pulse];
if ( self.style == TSAlertViewStyleInput )
{
[self layoutSubviews];
[self.inputTextField becomeFirstResponder];
}
}
with
#interface TSAlertOverlayWindow : UIWindow
{
}
#property (nonatomic,retain) UIWindow* oldKeyWindow;
#end
#implementation TSAlertOverlayWindow
#synthesize oldKeyWindow;
- (void) makeKeyAndVisible
{
self.oldKeyWindow = [[UIApplication sharedApplication] keyWindow];
self.windowLevel = UIWindowLevelAlert;
[super makeKeyAndVisible];
}
- (void) resignKeyWindow
{
[super resignKeyWindow];
[self.oldKeyWindow makeKeyWindow];
}
//
#end
add a new window, with new rootviewController, and subscribe it to
[[NSNotificationCenter defaultCenter] addObserver:(id) selector:(SEL) name:UIDeviceOrientationDidChangeNotification object:nil];
Windows don't autorotate. Ever. You should be adding this imageView to a UIViewController's view as the UIViewController has built in autorotation.
If you want to use a UIWindow to hold all your views, you will need to write your own transform code to handle rotations.