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

时间:2016-02-19 14:10:56

标签: ios objective-c cgrect rect aspect-fit

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

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

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

3 个答案:

答案 0 :(得分:2)

我写了一个应该达到你想要的功能。

在缩放它以适应给定的CGRect之后,它将返回给定innerRect的{​​{1}},同时保持宽高比。 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而言过宽,因此会根据其宽度进行缩放。

enter image description here

此处,红色区域为outerRect,绿色区域为innerRect它们最初都具有相同的高度,但在缩小后(因为它宽度是宽度的2倍,outerRect现在的高度是innerRect的一半。

此处outerRect作为子视图添加到innerRect如果您想将它们添加到同一个超级视图,可以将outerRect的{​​{1}}传递给该函数,而不是outerRect

答案 1 :(得分:1)

这里有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
    }
}

答案 2 :(得分:0)

    // 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]];

}

我认为这有助于你。