gpt4 book ai didi

ios - pan码更新center后UIView frame和center不相关?

转载 作者:行者123 更新时间:2023-11-29 13:14:17 26 4
gpt4 key购买 nike

enter image description here

所以我有一个精简的 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com