簡體   English   中英

泛碼更新中心后,UIView框架和中心是否不相關?

[英]UIView frame and center not correlated after pan code updates center?

在此處輸入圖片說明

因此,我得到了一個精簡的ViewController示例,該示例再現了這種行為,而我似乎無法纏住我的頭。 我正在使用帶有一些代碼的UIPanGestureRecognizer,該代碼正確地允許UIView在窗口中移動。 但是,如果我更新框架,甚至更新框架本身,視圖也會跳到意外位置,大概是基於視圖的中心。

我對此代碼有兩個問題。 首先,為什么視圖的中心位於最后一次觸摸的位置(基本上是將anchorPoint映射到視圖的邊界),並且顯然與視圖框架的中心無關?

其次,為什么在將frame屬性更改為當前值時視圖會移動? 在我看來,視圖的中心和框架只是部分相關,我不確定我缺少什么。

此示例僅在應用程序委托中創建一個基本的測試視圖控制器:

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;

我真的看不到這條線怎么會導致視圖移動,除非以前的center屬性沒有“完全粘住”或其他東西。 此外,我不了解center屬性的值,因為它似乎是最后觸摸的地方,而不是視圖的中心。 日志示例:

AnchorPoint: {0.204427, 0.748506}
Center: {625, 218.5}
Frame: {{14, -34}, {768, 1004}}

從長遠來看,我試圖在這里實現的是一個可以縮放的視圖,但是當滾動到邊緣之外時,它將回彈(就像UIScrollView一樣)。

如果刪除這兩行

    view.layer.anchorPoint = CGPointMake(locationInView.x / view.bounds.size.width, locationInView.y / view.bounds.size.height);
    view.center = locationInSuperview;

然后,您的視圖平移將達到您的預期。 為什么仍要更改圖層的定位點? 通常,您要實現的代碼看起來過於復雜。 請參閱DavidRönnqvist, 了解錨點了解如何更改錨點會對視圖的幀屬性產生(通常是意外的)影響。

此外,通常最好不要self.view頂級視圖(視圖控制器的self.view )並操作子視圖。 這樣,您就知道一切都與viewController的視圖相關聯,而不必懷疑UIWindow的狀況。 旋轉設備時,旋轉變換將應用於該頂層視圖,這在檢查框架數據時無濟於事。 子視圖的屬性不受該轉換的影響。

您的代碼在未轉換的縱向模式下的行為與預期的一樣,並且僅在橫向或縱向倒置時會拋出奇怪的結果。 在這些情況下,視圖已應用旋轉變換。 蘋果公司說,將變換應用於視圖后,框架的origin屬性是未定義的,因此在執行此操作時:

self.view.frame = self.view.frame

您正在分配處於未定義狀態的屬性。 期待意外。

您可以這樣更改視圖加載代碼:

- (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,而讓它自動創建頂層視圖,然后在viewDidLoad實現一個子視圖。 現在,您的測試應用程序可以正常運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM