旋转期间 UIScrollView 的 contentOffset

发布于 2024-09-17 06:17:35 字数 1144 浏览 3 评论 0原文

我想在旋转更改期间手动更新 UIScrollViewcontentOffset 。滚动视图填充屏幕并具有灵活的宽度和高度。

我目前正在尝试更新 willRotateToInterfaceOrientation 中的 contentOffset,如下所示:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [Utils logPoint:myScrollView.contentOffset tag:@"initial"];
    myScrollView.contentOffset = CGPointMake(modifiedX, modifiedY);
    [Utils logPoint:myScrollView.contentOffset tag:@"modified"];
}

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [Utils logPoint:myScrollView.contentOffset tag:@"final"];
}

但是,最终值不是修改后的值,它似乎受到它的影响,但我不清楚如何。

这些是我得到的一些结果:

initial: (146.000000;-266.000000)
modified: (81.000000;-108.000000)
final: (59.000000;-0.000000)

initial: (146.000000;-266.000000)
modified: (500.000000;500.000000)
final: (59.000000;500.000000)

initial: (146.000000;-266.000000)
modified: (-500.000000;-500.000000)
final: (-0.000000;-0.000000)

How do I update the contentOffset of ascroll view during a spin change?

I want to manually update the contentOffset of an UIScrollView during rotation changes. The scroll view fills the screen and has flexible width and flexible height.

I'm currently trying to update the contentOffset in willRotateToInterfaceOrientation, like this:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [Utils logPoint:myScrollView.contentOffset tag:@"initial"];
    myScrollView.contentOffset = CGPointMake(modifiedX, modifiedY);
    [Utils logPoint:myScrollView.contentOffset tag:@"modified"];
}

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [Utils logPoint:myScrollView.contentOffset tag:@"final"];
}

However, the final value is not the modified value, and it kinda seems to be influenced by it, but it's not evident to me how.

These are some of the results that I get:

initial: (146.000000;-266.000000)
modified: (81.000000;-108.000000)
final: (59.000000;-0.000000)

initial: (146.000000;-266.000000)
modified: (500.000000;500.000000)
final: (59.000000;500.000000)

initial: (146.000000;-266.000000)
modified: (-500.000000;-500.000000)
final: (-0.000000;-0.000000)

How do I update the contentOffset of a scroll view during a rotation change?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初相遇 2024-09-24 06:17:35

将我的评论转换为答案:)

尝试从 willAnimateRotationToInterfaceOrientation:duration: 中更改 contentOffset 。那时动画块应该就位,操作系统会将您对 contentOffset 的更改视为属于旋转引起的更改。

如果您之前更改了 contentOffset,系统似乎不会将这些更改视为属于旋转,并且仍然应用旋转调整大小,这次是从新尺寸开始。

Converting my comment to an answer :)

Try changing contentOffset from within willAnimateRotationToInterfaceOrientation:duration: instead. An animation block should be in place by then, and the OS regards your changes to contentOffset as belonging to the changes caused by the rotation.

If you change contentOffset before, it looks like the system doesn't respect these changes as belonging to the rotation, and still applies rotation-resizing, this time starting from your new dimensions.

俯瞰星空 2024-09-24 06:17:35

当在 UIScrollView 上启用分页并且要维护页面偏移时,以下代码片段可以解决问题。

声明一个属性,该属性将计算 currentPage 在旋转之前的位置,并在 viewDidLoad 中将其设置为 -1

@property (assign, nonatomic) NSInteger lastPageBeforeRotate;

然后重写 willRotateToInterfaceOrientation:toInterfaceOrientation:duration 方法并将计算值分配给它。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    int pageWidth = self.scrollView.contentSize.width / self.images.count;
    int scrolledX = self.scrollView.contentOffset.x;
    self.lastPageBeforeRotate = 0;

    if (pageWidth > 0) {
        self.lastPageBeforeRotate = scrolledX / pageWidth;
    }

    [self showBackButton:NO];
}

然后我们确保在执行旋转之前,正确设置滚动视图的内容偏移量,以便将其聚焦到我们的 lastPageBeforeRotate

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        if (self.lastPageBeforeRotate != -1) {
            self.scrollView.contentOffset = CGPointMake(self.scrollView.bounds.size.width * self.lastPageBeforeRotate, 0);
            self.lastPageBeforeRotate = -1;
        }
}

Following snippets does the trick when paging is enabled on UIScrollView and page offset is to be maintained.

Declare a property which will calculate position of currentPage before rotation, and set it to -1 in viewDidLoad

@property (assign, nonatomic) NSInteger lastPageBeforeRotate;

Then override the willRotateToInterfaceOrientation:toInterfaceOrientation:duration method and assign calculated value to it.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    int pageWidth = self.scrollView.contentSize.width / self.images.count;
    int scrolledX = self.scrollView.contentOffset.x;
    self.lastPageBeforeRotate = 0;

    if (pageWidth > 0) {
        self.lastPageBeforeRotate = scrolledX / pageWidth;
    }

    [self showBackButton:NO];
}

Then we ensure that before rotation is performed, we set our scrollview's content offset correctly, so as to focus it to our lastPageBeforeRotate

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        if (self.lastPageBeforeRotate != -1) {
            self.scrollView.contentOffset = CGPointMake(self.scrollView.bounds.size.width * self.lastPageBeforeRotate, 0);
            self.lastPageBeforeRotate = -1;
        }
}
甜心小果奶 2024-09-24 06:17:35

更新了 iOS 8+ 的答案

在控制器中实现 viewWillTransitionToSize:withTransitionCoordinator: 。

例子:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    NSUInteger visiblePage = (NSInteger) self.scrollView.contentOffset.x / self.scrollView.bounds.size.width;

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        self.scrollView.contentOffset = CGPointMake(visiblePage * self.scrollView.bounds.size.width, self.scrollView.contentOffset.y);
    } completion:nil];
}

Updated answer for iOS 8+

Implement viewWillTransitionToSize:withTransitionCoordinator: in your controller.

Example:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    NSUInteger visiblePage = (NSInteger) self.scrollView.contentOffset.x / self.scrollView.bounds.size.width;

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        self.scrollView.contentOffset = CGPointMake(visiblePage * self.scrollView.bounds.size.width, self.scrollView.contentOffset.y);
    } completion:nil];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文