【问题标题】:skew UIView without giving perspective and keeping heigh and width倾斜 UIView 而不给出透视并保持高度和宽度
【发布时间】:2016-06-15 23:52:42
【问题描述】:

你好,

我正在尝试实现图像中的转换,但我只有一个类似的转换,但使用 CGATransform3D 进行透视(我不想要)。我如何使用objective-c来实现这一点?转换后的图像应具有与原始图像相同的高度和宽度,但底部倾斜给定角度。

提前感谢您的帮助。

【问题讨论】:

  • 你可以使用 Core Image。

标签: ios objective-c transform skew


【解决方案1】:

这是一种“剪切”或“倾斜”变换。幸运的是,剪切变换是仿射变换,iOS 支持 UIViewCALayer 级别的仿射变换。但是,它没有方便的函数来构造剪切变换,所以让我们写一个:

static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
    return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}

xShearyShear 的确切含义并不明显。 xShear 是 y 轴倾斜角度的切线,yShear 是 x 轴倾斜角度的切线。这可能看起来倒退,但它具有您期望的视觉效果:非零 xShear 使图形向左或向右倾斜,非零 yShear 使图形向上或向下倾斜。

由于 tan π/4 = 1(或者,如果您愿意,tan 45° = 1),affineTransformMakeShear(1, 0) 返回的变换将矩形变成左右边缘为 π/4 弧度(或45°)。

演示:

请注意,两个轴上的剪切可以等同于旋转和缩放的组合。

这是我的演示代码:

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) IBOutlet UIView *shearedView;
@property (strong, nonatomic) IBOutlet UISlider *verticalShearSlider;
@property (strong, nonatomic) IBOutlet UISlider *horizontalShearSlider;
@property (strong, nonatomic) IBOutlet UILabel *verticalShearLabel;
@property (strong, nonatomic) IBOutlet UILabel *horizontalShearLabel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self updateAppearance:nil];
}

static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
    return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}

- (IBAction)updateAppearance:(id)sender {
    CGFloat xShear = self.horizontalShearSlider.value;
    CGFloat yShear = self.verticalShearSlider.value;
    self.shearedView.transform = affineTransformMakeShear(xShear, yShear);
    self.horizontalShearLabel.text = [NSString stringWithFormat:@"%.2f", xShear];
    self.verticalShearLabel.text = [NSString stringWithFormat:@"%.2f", yShear];
}

@end

【讨论】:

  • 非常感谢!!这比我想象的更棒更容易! :D
  • @rob 你有最好的演示老兄 :) 如果有一天有人把这些经典改成 Swift 会很酷...
  • @rob mayoff 我还是不明白,如何以弧度或度数提供角度值?
  • tan(angle) 传递给affineTransformMakeShear
  • 有趣的注意:UIView 是根据其中心进行变换,而 CGRect 是根据其左上角顶点进行变换。
猜你喜欢
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 2011-03-24
  • 2014-06-12
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多