7

适用于 iOS 的 Tweetbot 和 Kickstarter 在具有横幅图像的用户个人资料上使用了一项很酷的功能。如果你下拉tableView图像缩放。

我使用以下方法使其部分工作,它改变了图像的高度,但奇怪的是,不是宽度:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    UIImageView *imageView = (UIImageView *)self.tableView.tableHeaderView;
    CGFloat y = -scrollView.contentOffset.y;
    imageView.frame = CGRectMake(0, scrollView.contentOffset.y, self.cachedImageViewSize.size.width+y, self.cachedImageViewSize.size.height+y);
    NSLog(@"%@", NSStringFromCGRect(imageView.frame));

}

有谁知道如何重现这种效果?

4

6 回答 6

35

好的,我想通了。这是我所做的:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"church-welcome.png"]];
    self.imageView.contentMode = UIViewContentModeScaleAspectFill;
    self.cachedImageViewSize = self.imageView.frame;
    [self.tableView addSubview:self.imageView];
    [self.tableView sendSubviewToBack:self.imageView];
    self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 170)];

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    CGFloat y = -scrollView.contentOffset.y;
    if (y > 0) {
        self.imageView.frame = CGRectMake(0, scrollView.contentOffset.y, self.cachedImageViewSize.size.width+y, self.cachedImageViewSize.size.height+y);
        self.imageView.center = CGPointMake(self.view.center.x, self.imageView.center.y);
    }

}
于 2013-02-20T23:39:17.827 回答
1

斯威夫特的上述答案:

可变减速:

var imageView: UIImageView!
var cachedImageViewSize: CGRect!

viewDidLoad:

var imageView: UIImageView!
var cachedImageViewSize: CGRect!

override func viewDidLoad() {
    super.viewDidLoad()

    self.imageView = UIImageView(image: UIImage(named: "image-plane"))
    imageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 170)
    self.imageView.contentMode = .ScaleAspectFill
    self.cachedImageViewSize = self.imageView.frame
    self.tableView.addSubview(self.imageView)
    self.imageView.center = CGPointMake(self.view.center.x, self.imageView.center.y)
    self.tableView.sendSubviewToBack(self.imageView)
    self.tableView.tableHeaderView = UIView(frame: CGRectMake(0, 0, self.view.frame.size.width, 170))
}

scrollViewDidScroll:

override func scrollViewDidScroll(scrollView: UIScrollView) {

        let y: CGFloat = -scrollView.contentOffset.y
        if y > 0 {
            self.imageView.frame = CGRectMake(0, scrollView.contentOffset.y, self.cachedImageViewSize.size.width + y, self.cachedImageViewSize.size.height + y)
            self.imageView.center = CGPointMake(self.view.center.x, self.imageView.center.y)
        }
    }
于 2016-09-07T11:14:48.700 回答
1

Nic Hubbard 的 Swift 3.0 版本的回答:

override func viewDidLoad() {

    self.imageView = UIImageView(image: UIImage(named: "header-image"))
    imageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 170)
    self.imageView.contentMode = .scaleAspectFill
    self.cachedImageViewSize = self.imageView.frame
    self.tableView.addSubview(self.imageView)

    self.imageView.center = CGPoint(x: self.view.center.x, y:self.imageView.center.y)
    self.tableView.sendSubview(toBack: self.imageView)
    self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 170))
}

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let y: CGFloat = -scrollView.contentOffset.y
    if y > 0 {
        self.imageView.frame = CGRect(x: 0, y: scrollView.contentOffset.y, width: self.cachedImageViewSize.size.width + y, height: self.cachedImageViewSize.size.height + y)
        self.imageView.center = CGPoint(x: self.view.center.x, y: self.imageView.center.y)
    }
}
于 2017-07-12T16:08:07.150 回答
0

我认为它只是调整图像视图的大小以适应垂直空间,同时保持相同的纵横比。

于 2013-02-20T22:37:09.270 回答
0

Nic Hubbard 的 Swift 2 版本的回答:

var imageView: UIImageView!
var cachedImageViewSize: CGRect!

override func viewDidLoad(){

   super.viewDidLoad()

   self.imageView = UIImageView(image: UIImage(named: "church-welcome.png"))
   self.imageView.contentMode = .ScaleAspectFill
   self.cachedImageViewSize = self.imageView.frame
   self.tableView.addSubview(self.imageView)
   self.tableView.sendSubviewToBack(self.imageView)
   self.tableView.tableHeaderView = UIView(frame: CGRectMake(0, 0, self.view.frame.size.width, 170))

}

func scrollViewDidScroll(scrollView: UIScrollView) {
var y: CGFloat = -scrollView.contentOffset.y
if y > 0 {
    self.imageView.frame = CGRectMake(0, scrollView.contentOffset.y, self.cachedImageViewSize.size.width + y, self.cachedImageViewSize.size.height + y)
    self.imageView.center = CGPointMake(self.view.center.x, self.imageView.center.y)
   }
}
于 2016-03-02T22:51:39.820 回答
0

上述解决方案实际上并不能真正提供它在 Tweetbot 或 Tinder [目标的个人资料图片缩放] 中的确切实现方式。

我还必须解决这个问题,我发现最完美的实现是使用 2 个主要元素:

1)具有内容插图的表格视图

2)该表视图顶部的图像视图,该视图具有顶部约束和高度约束的出口,并且位于表视图内容插图提供的空白空间的顶部。

所以首先要确保为 tableView 设置插图和为 imageView 设置初始高度约束。例如,您可以在 viewDidLoad 中执行此操作。

imageViewHeightConstraint.constant = view.frame.height * 0.3
tableView.contentInset = UIEdgeInsets(top: view.frame.height * 0.3, left: 0, bottom: 0, right: 0)

然后只需听 w scrollViewDidScroll 委托方法并相应地修改约束。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let contentOffset = scrollView.contentOffset.y

    if -contentOffset >= view.frame.height * 0.3 {
        //reset the top constraint
        topConstraint.constant = 0
        //make the imageview bigger by the additional content offset value
        imageViewHeightConstraint.constant = -contentOffset
    } else {
        topConstraint.constant = -(view.frame.height * 0.3 + contentOffset)
    }
}

您可能需要根据自己设置约束的方式反转符号。也许有一种方法可以优化而不是经常修改约束,但你明白了。

另请注意,您需要:

imageView.contentMode = .scaleAspectFill
layer.masksToBounds = true

否则,图像将被绘制在您的第一个 tableView 单元格之上[取决于它可能覆盖整个表格视图的图像大小],因为它是在其“边界”之外绘制的。

于 2017-08-24T02:03:39.920 回答