- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我有一个精简的 ViewController 示例,它重现了我似乎无法理解的这种行为。我正在使用 UIPanGestureRecognizer 和一些代码,这些代码可以正确地允许 UIView 在窗口中移动。但是,如果我更新框架,即使是更新框架本身, View 也会跳到一个意想不到的位置,大概是基于 View 的中心。
关于这段代码我有两个问题。首先,为什么 View 的中心是最后一次触摸的位置(基本上是映射到 View 边界的 anchor ),而且显然与 View 框架的中心没有任何关系?
其次,为什么将 frame 属性更改为当前值时 View 会移动?在我看来, View 的中心和框架只是部分相关,我不确定我遗漏了什么。
这个例子只是在应用委托(delegate)中创建了一个基本的测试 View Controller :
TestViewController *vc = [[TestViewController alloc] init];
self.window.rootViewController = vc;
TestViewController.m:
#import "TestViewController.h"
#import <QuartzCore/QuartzCore.h>
@implementation TestViewController
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 748)];
self.view.backgroundColor = UIColor.redColor;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)];
pan.maximumNumberOfTouches = 1;
[self.view addGestureRecognizer:pan];
}
- (void)onPan:(UIPanGestureRecognizer*)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) {
UIView *view = recognizer.view;
CGPoint locationInView = [recognizer locationInView:view];
CGPoint locationInSuperview = [recognizer locationInView:view.superview];
view.layer.anchorPoint = CGPointMake(locationInView.x / view.bounds.size.width, locationInView.y / view.bounds.size.height);
view.center = locationInSuperview;
}
if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [recognizer translationInView:[recognizer.view superview]];
[recognizer.view setCenter:CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y+translation.y)];
[recognizer setTranslation:CGPointZero inView:[recognizer.view superview]];
}
if(recognizer.state == UIGestureRecognizerStateEnded) {
NSLog(@"AnchorPoint: %@", NSStringFromCGPoint(self.view.layer.anchorPoint));
NSLog(@"Center: %@", NSStringFromCGPoint(self.view.center));
NSLog(@"Frame: %@", NSStringFromCGRect(self.view.frame));
self.view.frame = self.view.frame;
}
}
@end
当平移手势结束时,如果我删除以下行,平移会按预期工作:
self.view.frame = self.view.frame;
我真的不明白那条线是如何导致 View 四处移动的,除非之前的 center 属性没有“完全粘住”之类的。此外,我不明白 center 属性的值(value),因为它似乎是最后触摸的地方,而不是 View 的中心。示例日志:
AnchorPoint: {0.204427, 0.748506}
Center: {625, 218.5}
Frame: {{14, -34}, {768, 1004}}
从长远来看,我在这里尝试实现的是一个可以缩放的 View ,但是当滚动到边缘之外时会快速返回(就像 UIScrollView 那样)。
最佳答案
如果去掉这两行
view.layer.anchorPoint = CGPointMake(locationInView.x / view.bounds.size.width, locationInView.y / view.bounds.size.height);
view.center = locationInSuperview;
然后您的 View 平移将按照您的预期运行。你为什么要改变图层的 anchor 呢?一般来说,您的代码对于您要实现的目标来说似乎过于复杂。参见 David Rönnqvist,understanding the anchor point关于更改 anchor 如何(通常是意想不到的)影响 View 的框架属性。
此外,单独保留顶层 View ( View Controller 的 self.view
)并操作 subview 通常是个好主意。这样你就知道一切与 viewController 的 View 是如何相关的,而不用想知道 UIWindow 发生了什么。当您旋转设备时,旋转变换将应用于该顶层 View ,这在您检查帧数据时无济于事。它的 subview 的属性不受该转换的影响。
您的代码在未转换的纵向模式下的行为与您预期的一样,并且只会在横向或纵向颠倒时抛出奇怪的结果。这些是 View 应用了旋转变换的情况。 Apple 表示当对 View 应用变换时,框架的 origin 属性未定义,因此当您这样做时:
self.view.frame = self.view.frame
您正在分配未定义状态的属性。期待意外。
您可以这样更改您的 View 加载代码:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView* subview = [[UIView alloc] initWithFrame:
CGRectMake(0, 0
, self.view.bounds.size.width
, self.view.bounds.size.height)];
[self.view addSubview:subview];
subview.backgroundColor = UIColor.redColor;
[subview setAutoresizingMask:UIViewAutoresizingFlexibleWidth
|UIViewAutoresizingFlexibleHeight];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:@selector(onPan:)];
pan.maximumNumberOfTouches = 1;
[subview addGestureRecognizer:pan];
}
这里我们不覆盖-loadView,让它自动创建顶层 View ,然后我们在viewDidLoad
中实现一个 subview 。现在您的测试应用可以正常运行。
关于ios - pan码更新center后UIView frame和center不相关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16234631/
最近,我在 XCode 上的调试器停止正常工作,并给出了以下错误: 此帧内的前一帧(gdb 无法展开超过此帧) 我已经浏览过 SO 的另一个线程,谈论丢失的符号。我通过删除符号目录并让它从 iPod
当我在设备上遇到断点时,出现以下调试器错误: 来自调试器的错误:此帧内的上一帧(gdb 无法展开超过此帧) 当应用程序遇到断点时,就会发生这种情况。如果我点击调试器中的继续按钮,它会愉快地继续,直到下
如何在 WinRT XAML 应用程序中操作框架的历史记录? 用户将从我的中心页面开始,他们可以在其中选择一个现有项目以转到其编辑屏幕,或者他们可以选择“新项目”。 “新项目”将引导他们完成一个简短的
2 帧,我希望第 2 帧“覆盖”/更新第 1 帧。基本上,其中 Table1-colB-value = Table2-oldB-value,用 Table2-newB-value 覆盖 Table1-
我正在尝试逐帧动画,但它给了我一个强制关闭,我不确定为什么它给我一个强制关闭。在我看来一切都很好。 这是我的代码,我希望有人能帮忙吗?提前致谢。 动画测试.java import android.ap
这是我的主课。 package pomsystem; public class POMSystem { public static void main(String[] args) {
如果为TRUE,我想从函数返回一个data.frame,否则使用return(ifelse(condition, mydf, NA)) 返回NA 但是, ifelse 会从 data.frame 中删
我正在处理两个 csv 文件并导入为数据框 df1 和 df2 df1 有 50000 行,df2 有 150000 行。 我想比较(遍历每一行)df2 的“时间”df1,求时间差,返回所有列的值对应
我将许多文件夹中的小文本文件读取到一个列表中。因此,我有一个长度为 n 的列表,其中包含 2 个 data.frames。 这是列表元素 3 的示例(在问题末尾输入) ip_list[[3]] $`d
为了找出数据框 df.a 是否是数据框 df.b 的子集,我做了以下操作: df.a semi_join(df.b, df.a) Joining by: c("x", "y") x y 1 1
在某些情况下,出于实现原因,我有一个只包含一个列的 data.frame df=as.data.frame(alpha=1:15) 如果我现在使用 df[-1, ] 它返回一个向量,但我想将它保留为一
Windows 8.1 商店应用中的 Frame.Navigate() 和 this.Frame.Navigate() 有什么区别? 这有什么区别 Frame.Navigate(typeof(Logi
我有两个 data.frames (df1, df2),我想用 df1$V2 的值替换 P1-P10 列中的字母值,但保留前两列df2. df1 = data.frame(V1=LETTERS, V2
有没有更好的方法来制作与现有 data.frame 具有相同维度、列名和行名的空白 data.frame? BAM<-read.table(~/myfile) # 10 rows and 10 co
我有一个列表 data.frame s。例如 set.seed(1) my_list result.df id var_p var_m var_d var_a
假设我有两个数据框 df1 和 df2 如下 Df1 Id Price Profit Month 10 5 2 1 10 5 3 2 10 5 2
我将创建一个网站,除了它自己的内容之外,它还将链接(在 iframe 中)到世界最大的报纸网站,如纽约时报、金融时报和其他一些网站。 但是我遇到了框架许可的问题。例如,纽约时报向我展示了一个错误 Lo
假设我有一个 data.frame: df x x A 1 10 2 20 3 30 从文档中(参见 ?"[" )您可以找到: If drop=TRUE the result is coer
我有一个想要克隆的现有 data.frame,但没有其中的值。 IE。我希望新框架具有与现有框架相同的列名称和类型。原始帧的大小可能为 GB 量级,因此复制和删除数据似乎不是正确的方法,并且迭代现有列
给定两个在列名称/数据类型方面相同的数据帧,其中某些列唯一标识行,是否有一种有效的函数/方法可以让一个数据帧“更新”另一个数据帧? 例如,在下面的例子中,原始和替换由'Name'和'Id'标识>。 g
我是一名优秀的程序员,十分优秀!