我正在使用 UIPageViewContoller 来创建类似书籍的翻页体验。我的书的页面比 iPhone 屏幕的全宽窄 18 像素,并固定在屏幕的左侧。然后,我的 UIPageViewController 视图的框架设置为这些页面的框架大小(宽度:302,高度:460)。我这样做是为了产生书有多个页面的效果,并且翻页看起来像是从当前可见页面的边缘开始,就像 iBooks 应用程序中的体验一样。
我遇到的问题是,如果有人尝试通过从屏幕最右侧平移超过 302 px 点来翻页,则 UIPageViewController 不会捕获平移手势,并且不会翻页。我看到很多用户尝试以这种方式翻页,所以我想在不改变 UI 设计的情况下修复这种体验。
我的想法是,我可以从 UIPageViewController 外部的区域获取 UIPanGesture 并将其传递给 UIPageViewController。我已经使用作为整个视图背景的图像视图成功捕获了平移手势,但我不知道如何将手势传递给 UIPageViewController 来处理翻页。
- (void) viewDidLoad {
...
// Add a swipe gesture recognizer to grab page flip swipes that start from the far right of the screen, past the edge of the book page
self.panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:nil] autorelease];
[self.panGesture setDelegate:self];
[self.iv_background addGestureRecognizer:self.panGesture];
//enable gesture events on the background image
[self.iv_background setUserInteractionEnabled:YES];
... …Run Code Online (Sandbox Code Playgroud) iphone uigesturerecognizer uipangesturerecognizer uipageviewcontroller
我正在使用 UIPanGestureRecognizer 来识别对象的拖动移动,它适用于以下状态:
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[panGesture setMaximumNumberOfTouches:1];
[panGesture setDelegate:self];
[self.view addGestureRecognizer:panGesture];
[panGesture release];
- (void)panAction:(UIPanGestureRecognizer *)gR
{
switch (gR.state)
{
case UIGestureRecognizerStateBegan:
NSLog(@"drag began");
break;
case UIGestureRecognizerStateChanged:
NSLog(@"drag moved");
break;
case UIGestureRecognizerStateEnded:
NSLog(@"drag ended");
break;
default:
break;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,是否可以检测用户开始拖动对象并在某个时刻停止拖动并将对象保持在固定点的情况?我已经检查过,当用户停止移动对象时,它会停止记录“更改”,直到用户开始移动对象或释放它(在这种情况下,它会记录“结束”)。这是一个示例日志:
2013-02-19 16:36:**01.181** Project[24201:10a03] drag began
2013-02-19 16:36:**14.004** Project[24201:10a03] drag moved
2013-02-19 16:36:14.221 Project[24201:10a03] drag moved
2013-02-19 16:36:**14.894** Project[24201:10a03] drag ended
Run Code Online (Sandbox Code Playgroud)
您可以看到开始、更改和结束之间有一些暂停(此时对象固定在某个点)。是否可以检测到这种情况?如果是这样,怎么办?任何帮助将不胜感激,提前致谢。
更新
我尝试过 UILongPressGestureRecognizer:
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
[longPressGesture setDelegate:self];
[self.view addGestureRecognizer:longPressGesture]; …Run Code Online (Sandbox Code Playgroud) 有没有办法确定 UIPageViewController 在左/右滑动时的平移位置?我一直在努力实现这一目标,但它不起作用。我添加了一个 UIPageViewController 作为子视图,我可以水平向左/右滑动它以在页面之间切换,但是我需要确定我在屏幕上平移的位置的 x,y 坐标。
我的问题:有没有办法调整 UIPanGestureRecognizer 的“灵敏度”,使其“更快”打开,即在移动较少数量的“像素”之后?
我有一个带有 UIImageView 的简单应用程序,以及与之相关的捏合和平移手势识别器,以便用户可以手动放大和绘制图像。工作正常。
但是,我注意到库存 UIPanGestureRecognizer 不会返回 UIGestureRecognizerState.Changed 的值,直到用户的手势移动大约 10 个像素。
示例:这是一个屏幕截图,显示了我尝试画得越来越短的几条线,并且有一个明显的有限长度,低于该长度就不会绘制任何线,因为平移手势识别器永远不会改变状态。
IllustrationOfProgressivelyShorterLines.png
...即,在黄线的右侧,我仍在尝试绘制,并且我的触摸被识别为 TouchMoved 事件,但 UIPanGestureRecognizer 没有触发自己的“Moved”事件,因此没有绘制任何内容。
(注/说明:该图像占据了我的 iPad 的整个屏幕,因此即使在识别器没有发生状态变化的情况下,我的手指也会物理移动超过一英寸。只是我们“放大”了根据捏合手势识别器生成的转换,因此图像的几个“像素”占据了屏幕的很大一部分。)
这不是我想要的。关于如何修复它有什么想法吗?
如果我对 UIPanGestureRecognizer 进行子类化或类似的东西,也许我可以得到 UIPanGestureRecognizer 的一些“内部”参数?我想我会尝试以某种方式对识别器进行子类化,例如......
class BetterPanGestureRecognizer: UIPanGestureRecognizer {
var initialTouchLocation: CGPoint!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
initialTouchLocation = touches.first!.locationInView(view)
print("pan: touch begin detected")
print(self.state.hashValue) // this lets me check the state
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesMoved(touches, withEvent: event)
print("pan: touch move detected")
print(self.state.hashValue) …Run Code Online (Sandbox Code Playgroud) 当我拖动视图并将其放到新位置时,每次都会调用 .Ended 。
当我拖动视图一段时间并将其放在开始的同一位置时,没有任何内容被调用,我期望 .Ended 或 default 被调用,但没有发生。
为什么会出现这种情况?我如何了解用户何时持续释放视图?
var gestureRecognizer = UIPanGestureRecognizer(target: self, action: Selector("dragged:"))
gestureRecognizer.delegate = self
view.addGestureRecognizer(gestureRecognizer)
func dragged(gesture: UIPanGestureRecognizer) {
switch gesture.state {
case UIGestureRecognizerState.Began:
print("calls this everytime touch began")
case UIGestureRecognizerState.Ended:
print("doesn't call this everytime")
default:
print("never calls this")
}
}
Run Code Online (Sandbox Code Playgroud) 我试图确定是否有一种方法可以以编程方式设置手势识别器状态,以强制其在实际检测用户输入之前开始。
例如,当检测到长按时,我将平移手势识别器添加到图像中,如下所示;
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
myImage.addGestureRecognizer(longPressRecognizer)
func longPressed(sender: UILongPressGestureRecognizer) {
let mainWidth = UIScreen.mainScreen().bounds.width
let mainHeight = UIScreen.mainScreen().bounds.height
let myView: UIView(frame: CGRect(x: 0, y: 0, width: mainWidth, height: mainHeight)
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: "handlePan:")
myView.addGestureRecognizer(gestureRecognizer)
self.view.addSubview(myView)
}
Run Code Online (Sandbox Code Playgroud)
在该handlePan()函数中,我能够确定平移何时开始和结束;
func handlePan(gesture: UIPanGestureRecognizer) {
if gesture!.state == UIGestureRecognizerState.Began {
print("Started pan")
}
if gesture!.state == UIGestureRecognizerState.Ended {
print("Ended pan")
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,要检测手势何时开始,用户必须(1)长按图像,(2)释放手指,(3)按住并开始平移。理想情况下,我希望用户 (1) 长按图像,(2) 开始平移。
为了实现这一目标,我想我需要找到一种方法来“欺骗”事物,使其相信平移手势已经开始。
注意:实际上,比这里介绍的更复杂,这就是为什么我需要使用平移手势添加子视图,而不是直接将平移手势添加到图像。
目标是针对同一个 SCNScene 实现两种平移手势:一个用一根手指,另一个用两根手指。
下面的这段代码不起作用。即使为手势分配了不同的选择器,单指平移功能也永远不会被调用。一指平移和两指平移都会调用sceneViewPannedTwoFingers.
从阅读其他问题来看,这似乎shouldRecognizeSimultaneouslyWithGestureRecognizer可能是答案,但这些平移并不是同时发生的。它应该是单指平底锅或双指平底锅,不能同时使用两者。
是否可以有如上所述的两个平移手势?如果是这样,正确的方法是什么?
// Handle one-finger pans
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(sceneViewPannedOneFinger))
sceneView.addGestureRecognizer(panRecognizer)
// Handle two-finger pans
let twoFingerPanRecognizer = UIPanGestureRecognizer(target: self, action: #selector(sceneViewPannedTwoFingers))
sceneView.addGestureRecognizer(twoFingerPanRecognizer)
func sceneViewPannedTwoFingers(sender: UIPanGestureRecognizer) {
print("two finger pan!!!")
}
func sceneViewPannedOneFinger(sender: UIPanGestureRecognizer) {
print("one finger pan!!!")
}
Run Code Online (Sandbox Code Playgroud) 我有一个UICollectionView在我的UIViewController,我希望它响应UICollectionView.内部和外部的手势。默认情况下,UICollectionView它只响应它自己内部的手势,view但我怎样才能让它响应它外部的滑动view?
谢谢。
我正在尝试在我的 collectionViewCell 中实现 UISwipeGestureRecognizer,因此当您向左滑动时,单元格会消失。我想要实现的(我找不到方法)是为滑动设置动画,因此当我向左滑动单元格时,它会以淡入淡出效果消失。这是我在方法内的代码cellForItemAtindexPath
let cSelector = #selector(reset(sender:))
let UpSwipe = UISwipeGestureRecognizer(target: self, action: cSelector)
UpSwipe.direction = UISwipeGestureRecognizerDirection.left
cell.addGestureRecognizer(UpSwipe)
Run Code Online (Sandbox Code Playgroud)
方法
func reset(sender: UISwipeGestureRecognizer) {
let cell = sender.view as! UICollectionViewCell
let i = self.collectionView?.indexPath(for: cell)!.item
self.messages.remove(at: i!)
self.collectionView?.reloadData()
}
Run Code Online (Sandbox Code Playgroud)
谢谢!!!
编辑: 我想我找到了最简单的方法,但我遇到了一些麻烦。我尝试在单元格中实现 UIPanGestureRecognizer。这就是它的样子......
项目单元格
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gestureRecognizer:)))
cell.addGestureRecognizer(gestureRecognizer)
Run Code Online (Sandbox Code Playgroud)
方法
func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began {
// When the drag is first recognized, you can get the starting coordinates here
}
if gestureRecognizer.state …Run Code Online (Sandbox Code Playgroud) 假设我有一个动画师将视图从 移动(0, 0)到(-120, 0):
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.8)
animator.addAnimations {
switch state:
case .normal: view.frame.origin.x = 0
case .swiped: view.frame.origin.x = -120
}
}
Run Code Online (Sandbox Code Playgroud)
我将它与 一起使用UIPanGestureRecognizer,这样我就可以随着手指的移动不断调整视图的大小。
当我想在动画开始或结束时添加某种弹跳效果时,就会出现问题。不仅仅是阻尼比,还有弹跳效果。最简单的想象方法是 的“滑动删除”功能UITableViewCell,您可以将“删除”按钮拖动到超出其实际宽度,然后它会弹回来。
实际上,我想要实现的是在段fractionComplete之外设置属性的方法[0, 1],因此当分数为 时1.2,偏移量将变为144而不是其最大值 120。
现在 的最大值fractionComplete正是1。
以下是一些可视化此问题的示例:
编辑(1 月 19 日):
抱歉我的回复迟了。以下是一些说明:
我不使用UIView.animate(...),而是UIViewPropertyAnimator出于一个非常具体的原因使用:它为我处理所有的计时、曲线和速度。
例如,您将视图拖动到一半。这意味着剩余部分的持续时间应比总持续时间短两倍。或者,如果您拖动了 99% 的距离,它应该几乎立即完成剩余部分。
作为补充,UIViewPropertyAnimator具有诸如暂停(当用户再次开始拖动时)或反向(当用户开始向左拖动,但之后他改变主意并将手指移到右侧时)等功能,我也受益于。
所有这些对于简单的 UIView 动画来说是不可用的,或者最多需要大量的努力。它只能进行简单的转换,但事实并非如此。
这就是为什么我 …
animation bounce uipangesturerecognizer swift uiviewpropertyanimator