【问题标题】:How do I center an iOS UIView subview in the root view programmatically?如何以编程方式在根视图中居中 iOS UIView 子视图?
【发布时间】:2019-03-07 00:04:49
【问题描述】:

有大量的 UIView 居中问题和答案,但我没有找到符合我的标准的问题和答案。我有一个 UIImageView 子类,它是另一个(相同) UIImageView 子类的子视图。我需要能够“重置”我的 UIImageView 子类,以便通过用户交互它位于屏幕中心(根视图控制器的视图)。

只是这样做:

- (void)reset {
    [self setCenter: self.superview.center];
}

...不起作用,因为中心点位于超级视图的坐标系中,而不是根视图。超级视图可以拖离根视图的中心很远。

最初,我循环遍历 superview 层次结构以找到根视图,但仍然无法正常工作,这再次是因为用户可以在嵌套视图的每个级别应用到每个 UIImageView 子类的不同坐标系和各种比例.

我没有找到关于 SO 的完整解决方案,所以我自己编写并发布在这里。希望它可以为其他人节省一些时间并进行探索。

【问题讨论】:

    标签: ios objective-c uiview uiimageview


    【解决方案1】:

    要使 UIView 在“屏幕”中居中,您需要将其相对于根视图控制器的视图居中。如果您以编程方式对 UIView 或其子类(例如 ImageView)进行子类化,并且您的超级视图不是视图控制器的视图,这将非常有用。这是一种将视图置于根视图中心的方法,无论它位于视图层次结构中的什么位置:

    // center the view in the root view
    - (void)centerInRootview:UIView *view {
        UIView *rootview = UIApplication.sharedApplication.keyWindow.rootViewController.view;
    
        // if the view hierarchy has not been loaded yet, size will be zero
        if (rootview.bounds.size.width > 0 &&
            rootview.bounds.size.height > 0) {
            CGPoint rootCenter = CGPointMake(CGRectGetMidX(rootview.bounds),
                                            CGRectGetMidY(rootview.bounds));
    
            // center the view relative to it's superview coordinates
            CGPoint center = [rootview convertPoint:rootCenter toView:view.superview];
    
            [view setCenter:center];
        }
    }
    

    这使用UIView.convertPoint:toView 方法将根视图的坐标系转换为您的视图的父视图的坐标系。

    我在UIView 类别中使用此方法,以便它可以从任何UIView 子类中使用。这里是View.h

    //
    // View.h - Category interface for UIView
    //
    #import <UIKit/UIKit.h>
    
    @interface UIView (View)
    - (void)centerInRootview;
    @end
    

    和 View.m:

    //
    // View.m - Category implementation for UIView
    //
    #import "View.h"
    
    @implementation UIView (View)
    
    // center the view in the root view
    - (void)centerInRootview {
        // make sure the view hierarchy has been loaded first
        if (self.rootview.bounds.size.width > 0 &&
            self.rootview.bounds.size.height > 0) {
            CGPoint rootCenter = CGPointMake(CGRectGetMidX(self.rootview.bounds),
                                            CGRectGetMidY(self.rootview.bounds));
    
            // center the view in it's superview coordinates
            CGPoint center = [self.rootview convertPoint:rootCenter toView:self.superview];
    
            [self setCenter:center];
        }
    }
    @end
    

    这里有一个简单的例子,说明如何从 UIImageView 子类中使用它。 ImageView.h:

    //
    // ImageView.h - Example UIImageView subclass
    //
    #import <UIKit/UIKit.h>
    
    @interface ImageView : UIImageView
    - (void)reset;
    @end
    

    还有 ImageView.m:

    #import "ImageView.h"
    
    @implementation ImageView
    
    - (void)reset {
        self.transform = CGAffineTransformIdentity;
    
        // inherited from UIImageView->UIView (View)
        [self centerInRootview];
    }
    @end
    

    【讨论】:

    • 我会使用AutoLayout 和中心约束来使子视图坚持到父中心。
    • 那么,现在所有的代码都没用了吗?你可以通过故事板实现同样的目标,对吧?
    • 我的 UIViews/UIImageViews 是通过编程方式创建的,而不是使用 StoryBoard。当用户选择某些菜单选项时,它们是在代码中创建的。然后用户可以随意平移、旋转和调整大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多