在iOS中以编程方式适合方面?

Posted

技术标签:

【中文标题】在iOS中以编程方式适合方面?【英文标题】:Aspect fit programmatically in iOS? 【发布时间】:2016-02-19 14:10:56 【问题描述】:

我想用宽高比选项将一个视图插入到另一个视图中。但由于某些原因,我不能只设置contentMode

您能否根据外部CGRect 调整内部CGRect 的大小来提供解决方案?

是的,有很多类似的问题,但没有人提供这样的解决方案。

【问题讨论】:

您可以在其他视图中创建枚举或字符串并将其设置在 viewdidLoad.Means 中,同时转到另一个控制器使用 AspectFit 设置 tat 枚举并在 viewdidLoad 中设置 tat 枚举 【参考方案1】:

我写了一个函数,应该可以实现你想要的。

它将返回给定innerRectCGRect,在将其缩放以适应给定outerRect 后,同时保持纵横比。 innerRect 将在 outerRect 中居中。

static inline CGRect aspectFitRect(CGRect outerRect, CGRect innerRect) 

    // the width and height ratios of the rects
    CGFloat wRatio = outerRect.size.width/innerRect.size.width;
    CGFloat hRatio = outerRect.size.height/innerRect.size.height;

    // calculate scaling ratio based on the smallest ratio.
    CGFloat ratio = (wRatio < hRatio)? wRatio:hRatio;

    // The x-offset of the inner rect as it gets centered
    CGFloat xOffset = (outerRect.size.width-(innerRect.size.width*ratio))*0.5;

    // The y-offset of the inner rect as it gets centered
    CGFloat yOffset = (outerRect.size.height-(innerRect.size.height*ratio))*0.5;

    // aspect fitted origin and size
    CGPoint innerRectOrigin = xOffset+outerRect.origin.x, yOffset+outerRect.origin.y;
    CGSize innerRectSize = innerRect.size.width*ratio, innerRect.size.height*ratio;

    return (CGRect)innerRectOrigin, innerRectSize;

你可以像这样使用它:

// outer rect
CGRect outerRect = CGRectMake(0, 100, self.view.bounds.size.width, 500);

// outer rect's view
UIView* v = [[UIView alloc] initWithFrame:outerRect];
v.backgroundColor = [UIColor greenColor];
[self.view addSubview:v];

// inner rect
CGRect innerRect = CGRectMake(0, 0, self.view.bounds.size.width*2, 500);
CGRect scaledInnerRect = aspectFitRect(v.bounds, innerRect);

// inner rect's view
UIView* v1 = [[UIView alloc] initWithFrame:scaledInnerRect];
v1.backgroundColor = [UIColor redColor];
[v addSubview:v1];

在这种情况下,innerRect 对于outerRect 来说太宽了,所以会根据它的宽度进行缩放。

这里,红色区域是innerRect,绿色区域是outerRect它们最初的高度相同,但缩小后(因为它是原来的2倍宽),innerRect 现在的高度是outerRect 的一半。

这里将innerRect 作为子视图添加到outerRect如果要将它们添加到同一个superview,可以将outerRectframe 传递给函数,而不是bounds

【讨论】:

【参考方案2】:

这里是 CGSize 和 CGRect 扩展,分别用于将一个尺寸拟合到另一个尺寸内,并将一个矩形拟合到另一个矩形内:

extension CGSize

    func sizeThatFitsSize(_ aSize: CGSize) -> CGSize
    
        let width = min(self.width * aSize.height / self.height, aSize.width)
        return CGSize(width: width, height: self.height * width / self.width)
    


extension CGRect

    func rectThatFitsRect(_ aRect:CGRect) -> CGRect
    
        let sizeThatFits = self.size.sizeThatFitsSize(aRect.size)

        let xPos = (aRect.size.width - sizeThatFits.width) / 2
        let yPos = (aRect.size.height - sizeThatFits.height) / 2

        let ret = CGRect(x: xPos, y: yPos, width: sizeThatFits.width, height: sizeThatFits.height)
        return ret
    

【讨论】:

【参考方案3】:
    // Your First View
    UIView *firstView = self;

    // Your second View
    UIView *secondView = [[UIView alloc] initWithFrame:CGRectZero]; change
    newSubview.translatesAutoresizingMaskIntoConstraints = NO;
    [containerView addSubview:newSubview];

    // Top Constraint
    [firstView addConstraint:[NSLayoutConstraint constraintWithItem:secondView
                                                              attribute:NSLayoutAttributeTop
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:firstView
                                                              attribute:NSLayoutAttributeTop
                                                             multiplier:1.0
                                                               constant:0.0]];
     // Leading Constraint                                                      
    [firstView addConstraint:[NSLayoutConstraint constraintWithItem:secondView
                                                              attribute:NSLayoutAttributeLeading
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:firstView
                                                              attribute:NSLayoutAttributeLeading
                                                             multiplier:1.0
                                                               constant:0.0]];
    // Bottom Constraint
    [firstView addConstraint:[NSLayoutConstraint constraintWithItem:secondView
                                                              attribute:NSLayoutAttributeBottom
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:firstView
                                                              attribute:NSLayoutAttributeBottom
                                                             multiplier:1.0
                                                               constant:0.0]];
    // Trailing Constraint
    [firstView addConstraint:[NSLayoutConstraint constraintWithItem:secondView
                                                              attribute:NSLayoutAttributeTrailing
                                                              relatedBy:NSLayoutRelationEqual
                                                                 toItem:firstView
                                                              attribute:NSLayoutAttributeTrailing
                                                             multiplier:1.0
                                                               constant:0.0]];


我认为这对你有帮助。

【讨论】:

如果您使用的是 CGRect,它不会自动调整所有尺寸的屏幕,这是一个很好的解决方案。 是的,但正如我所写的那样,我完全需要通过 CGRect 。我已经处理了所有的大小调整事件

以上是关于在iOS中以编程方式适合方面?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中以编程方式在标签栏上添加图像

在 iOS 中以编程方式生成视图

在 iOS 中以编程方式创建 UINavigationController

iOS 如何在 AppDelegate 中以编程方式设置侧边栏菜单?

在 iOS 中以编程方式对 UITableView 的约束

在 ios 中以编程方式获取墙纸