ios - 在 subview 上结合仿射变换使用 NSLayoutConstraint

标签 ios objective-c cocoa-touch autolayout

我需要垂直 slider 。为此,我有一个包含 UISliderUIView 类,在 initWithFrame: 中,我使用仿射变换将 slider 旋转 90学位。

我现在正在为其添加自动布局支持。

我希望允许 slider 以不同的长度进行实例化,以便它可以在动态的、自动布局的意义上使用。这是我正在尝试的代码,目的是让旋转的 slider 符合 UIView 的边界,位于 initWithFrame:

self = [super initWithFrame:frame];
if(self) {
    self.slider = [[UISlider alloc] init];
    [self addSubview:self.slider];
    self.slider.value = 0;

    self.slider.transform = CGAffineTransformMakeRotation(M_PI * 1.5);
    [self.slider setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute: NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute: NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute: NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute: NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];

    self.backgroundColor = [UIColor colorWithWhite:.8 alpha:1.0];
    self.layer.borderWidth = 1;
    self.slider.backgroundColor = [UIColor colorWithRed:.21 green:.95 blue:1 alpha:1];
    self.slider.layer.borderWidth = 1;

    return self;
}

这是结果 View 的样子。我实例化了三个不同的垂直 slider 。左边的帧为 300 x 300,右边的帧为 50 x 300,中间的帧为 300 x 50。我已经为 UIView 框架为灰色,并将 UISliders 的背景着色为蓝色。

Vertical Slider instances

300 x 300 的问题是我觉得我负担不起这么大的框架。周围会有其他观点,我担心那个观点会妨碍。

左边的问题是 slider 太小了。

中间那个的问题在于,由于 slider 已旋转出 View 的框架,因此无法捕获拇指并四处移动它。

我也试过将 slider 的顶部限制在 View 的右侧,将 slider 的右侧限制在 View 的底部,但这会产生错误和不可预测的结果。

我需要更改什么才能使这些约束起作用?

最佳答案

比看起来更简单。 UIView 父级全部设置为符合布局约束。它可以更简单地管理其 slider subview 这是整个类。这可以使用 initWithFrame: 在代码中创建,或者将 View 放入 IB 并设置类 == TwistedSlider。这就是全部...

@interface TwistedSlider ()
@property(weak,nonatomic) UISlider *slider;
@end

@implementation TwistedSlider

- (UISlider *)slider {
    if (!_slider) {
        UISlider *slider = [[UISlider alloc] init];
        [self addSubview:slider];
        _slider = slider;
    }
    return _slider;
}

// this works for any size of this view.  the slider will always be as tall as this view is wide
- (void)layoutSubviews {
    [super layoutSubviews];
    // size it to be as wide as this view's height, center it in this view
    self.slider.bounds = CGRectMake(0, 0, self.bounds.size.height, self.slider.bounds.size.height);
    self.slider.center = [self convertPoint:self.center fromView:self.superview];
    // rotate it
    self.slider.transform = CGAffineTransformMakeRotation(M_PI_2);
}

// that's it!
@end

关于ios - 在 subview 上结合仿射变换使用 NSLayoutConstraint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34318231/

相关文章:

objective-c - UITableViewCell 文本字段在滚动 tableview 时消失

objective-c - 混合两个图像并从两个 UIImageViews 绘制调整大小的图像

ios - iOS 上的 AUGraph 设置

ios - 仅选择整个单词 uiTextView

ios - IOS上的不同属性列表格式

ios - CLI 程序在检索解析结果之前退出

ios - iAd 的一些问题

ios - 区分收到的通知和触摸的通知

ios - 以编程方式在两个 UIViewController 之间切换

ios - 关于不直接调用 viewDidLoad 的文档?