带有ImageView的UIScrollView不能垂直滚动

时间:2015-04-24 11:42:06

标签: ios swift uiscrollview uiimageview

我有一个UIImageView,它的图像大于屏幕尺寸。我将此UIImageView作为UIScrollView的子视图。现在,我无法向下滚动。查看整个图像。但缩放功能正常。

@IBOutlet weak var scrollView: UIScrollView!

var imageView = UIImageView();

override func viewDidLoad() {
    super.viewDidLoad()
}

func centerScrollViewContents(){
    let boundsSize = scrollView.bounds.size
    var contentsFrame = imageView.frame

    if contentsFrame.size.width < boundsSize.width {
       contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2
    }
    else { 
       contentsFrame.origin.x = 0
    }

    if contentsFrame.size.height < boundsSize.height {            
        contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2
    }
    else {
        contentsFrame.origin.y = 0
    }

    imageView.frame = contentsFrame
   // scrollView.frame = contentsFrame        
}

func scrollViewDidZoom(scrollView: UIScrollView) {
    centerScrollViewContents()
}

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
    return imageView
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

    // Dispose of any resources that can be recreated.
}

override func viewDidAppear(animated: Bool) {

    scrollView.delegate = self
    imageView.frame = CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height)

   // imageView.contentMode = UIViewContentMode.ScaleAspectFill
   // imageView.clipsToBounds = true
    imageView.image = UIImage(named: imgstr)

    var imagee = UIImage(named: imgstr)
    let size = imagee?.size
   // imageView.frame = CGRectMake(0, 0, size.width!, size.height!)
    imageView.contentMode = .Top
    scrollView.addSubview(imageView)

    scrollView.contentSize = size!
    let scrollViewFrame = scrollView.frame
    let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
    let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
    let minScale = min(scaleHeight, scaleWidth)

    scrollView.minimumZoomScale = 1
    scrollView.maximumZoomScale = 5
    scrollView.zoomScale = minScale

    centerScrollViewContents()   
}

enter image description here

9 个答案:

答案 0 :(得分:4)

您必须解决UIScrollView工作

的两个主要问题
  1. 在初始化UIScrollView的所有数据的地方存在一个问题,我的意思是函数viewDidAppear
  2. 您必须为UIScrollViewTopBottomLeft设置Right的约束,以尊重您的SuperView
  3. 如果您将代码放在函数viewDidAppear内的viewDidLoad内并删除函数viewDidAppear,则可以正常使用。喜欢以下方式:

    override func viewDidLoad() {
        super.viewDidLoad()
    
    
        scrollView.delegate = self
        imageView.frame = CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height)
    
        // imageView.contentMode = UIViewContentMode.ScaleAspectFill
        // imageView.clipsToBounds = true
        imageView.image = UIImage(named: "imgstr.jpg")
    
        var imagee = UIImage(named: "imgstr.jpg")
        let size = imagee?.size
        // imageView.frame = CGRectMake(0, 0, size.width!, size.height!)
        imageView.contentMode = .Top
        scrollView.addSubview(imageView)
    
        scrollView.contentSize = size!
        let scrollViewFrame = scrollView.frame
        let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
        let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
        let minScale = min(scaleHeight, scaleWidth)
    
        scrollView.minimumZoomScale = 1
        scrollView.maximumZoomScale = 5
        scrollView.zoomScale = minScale
    
        centerScrollViewContents()
    }
    

    您还必须在故事板中设置UIScrollView的约束

    我认为问题在于以下区别:

      当视图实际可见时,会调用
    • viewDidAppear,并且可以在视图控制器的生命周期内多次调用(例如,当模式视图控制器被关闭并且视图再次可见时)。您可以在此处执行任何布局操作或在UI中执行任何绘图 - 例如,呈现模态视图控制器。但是,你在这里做的任何事都应该是可重复的。最好不要在这里保留东西,否则你会得到记忆 如果在视图消失时不释放它们,则会泄漏。
    • 当视图控制器首次加载到内存中时,
    • viewDidLoad只调用一次。这是您希望实例化任何实例变量并构建在此视图控制器的整个生命周期中存在的任何视图的位置。但是,此时通常尚未显示该视图。

    如果您有任何问题,我有一个项目准备好提交给Github,如果你想看到它。

      

    <强>更新:   在再次测试你的代码后,我将你的错误恢复到更少的代码。你的代码工作正常,如果你把你的代码imageView.frame = CGRectMake(0, 0, size!.width, size!.height)放在没有约束的情况下你的代码就可以了。

    这样的事情:

    override func viewDidAppear(animated: Bool) {
    
    
        scrollView.delegate = self        
    
        // imageView.contentMode = UIViewContentMode.ScaleAspectFill
        // imageView.clipsToBounds = true
        imageView.image = UIImage(named: "imgstr.jpg")
    
        var imagee = UIImage(named: "imgstr.jpg")
        let size = imagee?.size
    
        // This line should be here!!!
        imageView.frame = CGRectMake(0, 0, size!.width, size!.height)
        imageView.contentMode = .Top
        scrollView.addSubview(imageView)
    
        scrollView.contentSize = size!
        let scrollViewFrame = scrollView.frame
        let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
        let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
        let minScale = min(scaleHeight, scaleWidth)
    
        scrollView.minimumZoomScale = 1
        scrollView.maximumZoomScale = 5
        scrollView.zoomScale = minScale
    
        centerScrollViewContents()       
    
    }
    

    关键是,在之前的代码中,您将图片的frame设置为frame的{​​{1}},而不是图片大小超过{scrollView的{​​{1}} 1}}。

    我希望这对你有所帮助。

答案 1 :(得分:3)

确保您已为scrollview启用了userinteraction:scrollview.userInteractionEnabled=YES

答案 2 :(得分:2)

  • 将一个UIScrollView放入一个UIView(让它说容器视图)放在scrollview中,然后将imageview放在containerView中。

  • 现在将自动布局约束应用于uiscrollview,如此

left, right, top, bottom margins, width and height constraints in scrollview

  • 现在将自动布局约束应用于containerView

left, right, top, bottom margins, width and height constraints in containerView

  • 现在将自动布局约束应用于imageView

left, right, top, bottom constraints to the imageView

  • 之后你的autolayout结构必须像这样

autolayout structure

  • 之后在ViewController.m中编写以下代码

    - (void)viewWillAppear:(BOOL)animated
    {
       [super viewWillAppear:animated];
       [self.doubleTapGesture setNumberOfTapsRequired:2];
    }
    
    - (IBAction)handleDoubleTapGesture:(UITapGestureRecognizer *)sender 
    {    
       float newScale = self.scrollView.zoomScale *3;
     if (self.scrollView.zoomScale > self.scrollView.minimumZoomScale) 
      {
        [self.scrollView 
            setZoomScale:self.scrollView.minimumZoomScale animated:YES];
       }
       else       {      
        CGRect zoomRect = 
         [self zoomRectForScale:newScale
                       withCenter:
        [self.doubleTapGesture 
       locationInView:self.doubleTapGesture.view]];
           [self.scrollView zoomToRect:zoomRect animated:YES];
        }
      }
    
     - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center 
     {    
        CGRect zoomRect;
    
        zoomRect.size.height = 
           self.contentViewHeightConstraint.constant / scale;
        zoomRect.size.width  = 
            self.contentViewWidthConstraint.constant  / scale;
    
        center = [self.contentView 
            convertPoint:center fromView:self.view];
    
        zoomRect.origin.x = center.x - ((zoomRect.size.width / 2.0));
        zoomRect.origin.y = center.y - ((zoomRect.size.height / 2.0));
    
         return zoomRect;
     }
    
    #pragma mark - UIScrollViewDelegate
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        return self.contentView;
    }
    
    - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView 
                withView:(UIView *)view
    {
        self.ContentViewVerticalSpaceConstraint.constant = 0;
        [self.contentView layoutIfNeeded];
    }
    - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView 
                        withView:(UIView *)view atScale:(CGFloat)scale
    {
        if (scale <= 1)                    self.ContentViewVerticalSpaceConstraint.constant = 174;
            [self.contentView layoutIfNeeded];
        }
    }
    
  • 现在检查它是否可以正常工作,双击和捏合手势。

答案 3 :(得分:1)

试试这个:

imageView.frame = CGRectMake(0, 0, imageSize.height, imageSize.height)

或者

scrollView.contentSize = CGSizeMake(imageSize.width * 2, imageSize.height * 2)

通常,我会在 ViewDidLoad 中添加子视图。

答案 4 :(得分:1)

确保您的UIScrollView的高度不超过视图的高度本身。

示例代码

@IBOutlet weak var scroller: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    scroller.contentSize = CGSizeMake(400, 2300)
    scroller.showsHorizontalScrollIndicator = true
    scroller.scrollEnabled = true
}

参考:http://blog.revivalx.com/2015/02/23/how-to-use-scroll-view-in-xcode-6-ios-8xcode6/

答案 5 :(得分:1)

启用UIImageView用户交互。

imageView.userInteractionEnabled=true;

答案 6 :(得分:1)

为了垂直滚动您必须在scrollView的内容大小中将x轴设置为0。 并在viewDidLoad方法中设置它。

答案 7 :(得分:1)

您需要取消注释此行:

//imageView.frame = CGRectMake(0, 0, size.width!, size.height!)

当然,它会给你一个编译器错误。由于可选值是大小,因此正确的方法是:

imageView.frame = CGRectMake(0, 0, size!.width, size!.height)

答案 8 :(得分:0)

由于自动布局,它不能使用拖动手势滚动 在viewDidLoad中,自动布局会在您定义内容后重置内容大小。您有两个选择:可以禁用自动布局,也可以在viewDidLayoutSubviews中设置contentSize。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.contentSize = CGSize(width:10, height:10)
}