好的,我有一个带有左菜单和右视图控制器的应用程序,它们由UIPanGestureRecognizer控制。因此,当用户滑动屏幕边缘的边框(20px)时,它会导航。
在设置视图控制器中,我有UISwitch控制其他各种东西,但其中一个我想控制UIPanGestureRecognizer将接触多少次。
交换机设置正确,并将用户默认值发送到另一个视图控制器,但在接收端,它不会读取用户选择的内容。
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureCallback:)];
//Switch for SwipeNav
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:@"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[pan setMinimumNumberOfTouches:2];
[pan setMaximumNumberOfTouches:2];
}else{
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
}
[pan setDelegate:self];
[self.view addGestureRecognizer:pan];
当开关打开时,我怎么能这样做,它使用2个触摸来导航,然后关闭它就像正常一样?
任何帮助都会受到赞赏。谢谢。
使用设置同步代码更新。
if (swipe){
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:self.swipe.on forKey:@"SwipeNav"];
[userDefaults synchronize];
if ([swipe isOn]) {
[swipe setOn:YES animated:YES];
[self.tableView reloadData];
[[UIApplication sharedApplication] reloadInputViews];
} else {
[swipe setOn:NO animated:YES];
[self.tableView reloadData];
[[UIApplication sharedApplication] reloadInputViews];
}
}
答案 0 :(得分:0)
我创建了一个新项目,并尝试重现您所看到的问题,一切似乎都按预期工作。当开关打开时,你需要两个按钮来平移,当开关关闭时你只需要一个。如果这指向正确的方向,请告诉我。你的代码似乎是正确的。
我从How to use UIPanGestureRecognizer to move object? iPhone/iPad
复制粘贴了handlePan函数以编程方式创建所有内容并复制粘贴代码以保存交换机的状态。这是两个UIViewControllers
的代码//
// ViewController.m
// StackOverflowSwitch
//
//
//
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIButton *myButton;
@property (nonatomic,strong) UISwitch *switchOn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.myButton = [[UIButton alloc]initWithFrame:CGRectMake(10, 100, 150, 150)];
self.switchOn = [[UISwitch alloc]initWithFrame:CGRectMake(10, 300, 100, 100)];
self.myButton.backgroundColor =[UIColor grayColor];
[self.myButton setTitle:@"Click Me" forState:UIControlStateNormal];
[self.myButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.switchOn];
[self.view addSubview:self.myButton];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)click:(UIButton *)sender
{
[self performSegueWithIdentifier:@"NextViewController" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if(self.switchOn.on){
NSLog(@"switch is on");
}else{
NSLog(@"switch is off");
}
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:self.switchOn.on forKey:@"SwipeNav"];
[userDefaults synchronize];
}
@end
//////
#import "SecondViewController.h"
@interface SecondViewController() <UIGestureRecognizerDelegate>
@property (strong,nonatomic) UIView *myView;
@end
@implementation SecondViewController
-(void)viewDidLoad
{
[super viewDidLoad];
self.myView = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 200, 200)];
self.myView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.myView];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:@"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[pan setMinimumNumberOfTouches:2];
[pan setMaximumNumberOfTouches:2];
}else{
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
}
[pan setDelegate:self];
[self.view addGestureRecognizer:pan];
[self.myView addGestureRecognizer:pan];
}
-(void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
@end
/////更新
我不确定[[UIApplication sharedApplication] reloadInputViews];
如何调用函数来更新代码中的UIPanGestureRecongizer
,但我尝试通过调用每个setupView
方法尽可能接近地重新创建您的功能我点击UISwitch
的时间
我在那里创建了一个带有UIPanGestureReconginzer
的自定义视图,以及一个我从UIViewController调用以更新setNumberOfTouches
的方法。视图按预期工作。这里的关键不是初始化新的UIPanGuestureRecongizer
,而是更新现有的UIViewController
。我假设您的应用UIView
或UIPanGuestureRecongizer
中UIPanGuestureRecongizer
没有完全重新加载。
我创建了一个属性#import "MyTestView.h"
@interface MyTestView() <UIGestureRecognizerDelegate>
@property(nonatomic,strong) UIPanGestureRecognizer *panGesture;
@end
@implementation MyTestView
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self setupView];
}
return self;
}
-(UIPanGestureRecognizer *)panGesture
{
//lazy instantiation
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
}
return _panGesture;
}
-(void)setupView
{
//this gets called everytime the UISwitch is being pressed.
NSLog(@"Setup views");
self.backgroundColor = [UIColor redColor];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL switchOn = [userDefaults boolForKey:@"SwipeNav"];
if (switchOn) {
// 2 Finger SwipeNav
[self.panGesture setMinimumNumberOfTouches:2];
[self.panGesture setMaximumNumberOfTouches:2];
}else{
[self.panGesture setMinimumNumberOfTouches:1];
[self.panGesture setMaximumNumberOfTouches:1];
}
[self.panGesture setDelegate:self];
[self addGestureRecognizer:self.panGesture];
}
-(void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self];
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [recognizer velocityInView:self];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor),
recognizer.view.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
recognizer.view.center = finalPoint;
} completion:nil];
}
}
@end
,它在第一次被访问时被初始化,然后在按下开关时被更新。这是自定义UIView代码。如果您对代码有任何疑问,请与我们联系。
df = df.T
答案 1 :(得分:0)
好吧,经过多次测试/代码翻转后,我想我找到了解决方案。
所以多一点背景故事,我使用MMDrawerController,所以上面的方法关于放置[self setupView]; in(instancetype)initWithCoder没有做任何事情。 setupView或我的情况称为“setupGestureRecognizers”,它被加载到viewDidLoad中。其他任何地方根本不会加载手势。
使用我当前的切换代码和手势加载,我有:
-(UIPanGestureRecognizer *)panGestureNav {
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureCallback:)];
}
return _panGesture;
}
-(void)setupGestureRecognizers{
switchOn = [[NSUserDefaults standardUserDefaults] boolForKey:@"SwipeNav"];
if (switchOn == YES) {
// 2 Finger SwipeNav
[self.panGestureNav setMinimumNumberOfTouches:2];
[self.panGestureNav setMaximumNumberOfTouches:2];
NSLog(@"2 Finger Nav");
}else {
[self.panGestureNav setMinimumNumberOfTouches:1];
[self.panGestureNav setMaximumNumberOfTouches:1];
NSLog(@"Normal Nav");
}
[self.panGestureNav setDelegate:self];
[self.view addGestureRecognizer:self.panGestureNav];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureCallback:)];
[tap setDelegate:self];
[self.view addGestureRecognizer:tap];
}
这通常会有效,但是这个库做的事情有所不同,所以我必须调查他们的手势调用以及我最终做的是在这里调用它:
-(MMOpenDrawerGestureMode)possibleOpenGestureModesForGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer withTouch:(UITouch*)touch{
CGPoint point = [touch locationInView:self.childControllerContainerView];
MMOpenDrawerGestureMode possibleOpenGestureModes = MMOpenDrawerGestureModeNone;
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]){
[self setupGestureRecognizers]; <------------
所以现在它按照我的意愿加载和运行。
谢谢你,所以你的帮助。希望这有助于某人。