2016-08-03 15 views
11

thứ bậc Quan điểm của tôi là thế nàyLàm thế nào để thiết lập UIScrollView contensize khi nội dung là tải không đồng bộ

PhotoDetailViewController.swift 

    View 
     UIScrollView 
     UIImageView 

tôi thiết lập này bằng cách sử dụng kịch bản, và bổ sung bốn trở ngại (top = 0, đáy = 0, dẫn = 0, tailing = 0) để UIScrollView, bốn trở ngại (top = 0, đáy = 0, dẫn = 0, tailing = 0) để UIImageView, nhưng có hai lỗi nói

"ScrollView has ambiguous scrollable content width" 
"ScrollView has ambiguous scrollable content height" 

tôi hiểu rằng đây là vì tôi thiên đường' t đặt UIScrollView contentSize, nhưng những gì tôi cố gắng làm là tải ảnh từ PHAsset một cách không đồng bộ, vì vậy tôi chỉ có thể nhận được kích thước ảnh trong thời gian chạy. Vì vậy, câu hỏi là:

1: Cho rằng kích thước ảnh chỉ có thể đạt được khi chạy, cách giải quyết lỗi "nội dung có thể cuộn không rõ ràng"?

2: Tôi nên gọi PHImageManager.requestImageForAsset ở phương thức vòng đời nào của Chế độ xem? vì tôi nghĩ tôi nên đặt nội dung UIScrollViewSize theo lập trình, nhưng khi nào?

cập nhật với PhotoDetailViewController.swift

import UIKit 
import Photos 

class PhotoDetailViewController : UIViewController { 

@IBOutlet weak var scrollView: UIScrollView! 
@IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint! 
@IBOutlet weak var imageViewLeadingConstraint: NSLayoutConstraint! 
@IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint! 
@IBOutlet weak var imageViewTrailingConstraint: NSLayoutConstraint! 

var devicePhotosAsset : PHFetchResult! 
var index = 0 
var photo : UIImage! 
var imgManager:PHImageManager! 

@IBOutlet weak var imageView : UIImageView! 

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 
} 

override func awakeFromNib() { 
    self.imgManager = PHImageManager() 
} 

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

override func viewWillLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    updateMinZoomScaleForSize() 
    updateConstraintsForSize() 
} 

func displayPhoto() { 
    _ = self.imgManager.requestImageForAsset(self.devicePhotosAsset[self.index] as! PHAsset, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFit, options: nil, resultHandler: {(result, info) -> Void in 
      NSOperationQueue.mainQueue().addOperationWithBlock(){ 
       self.imageView.image = result 
      } 

     }) 
} 

private func targetSize() -> CGSize { 
    let scale = UIScreen.mainScreen().scale 
    let targetSize = CGSizeMake(CGRectGetWidth(self.imageView.bounds)*scale, CGRectGetHeight(self.imageView.bounds)*scale) 

    return targetSize 
} 

private func updateMinZoomScaleForSize() { 
    let size = scrollView.bounds.size 
    let widthScale = size.width/imageView.bounds.width 
    let heightScale = size.height/imageView.bounds.height 
    let minScale = min(widthScale, heightScale) 

    scrollView.minimumZoomScale = minScale 

    scrollView.zoomScale = minScale 
} 

func recenterImage(){ 
    let scrollViewSize = scrollView.bounds.size 
    let imageSize = imageView.frame.size 

    let horizontalSpace = imageSize.width < scrollViewSize.width ? (scrollViewSize.width - imageSize.width)/2 : 0 
    let verticalSpace = imageSize.height < scrollViewSize.height ? (scrollViewSize.height - imageSize.height)/2 : 0 
    scrollView.contentInset = UIEdgeInsets(top: verticalSpace, left: horizontalSpace, bottom: verticalSpace, right: horizontalSpace) 
} 

private func updateConstraintsForSize() { 
    let size = scrollView.bounds.size 
    let yOffset = max(0, (size.height - imageView.frame.height)/2) 
    imageViewTopConstraint.constant = yOffset 
    imageViewBottomConstraint.constant = yOffset 

    let xOffset = max(0, (size.width - imageView.frame.width)/2) 
    imageViewLeadingConstraint.constant = xOffset 
    imageViewTrailingConstraint.constant = xOffset 

    view.layoutIfNeeded() 
} 
} 

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

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

Trả lời

2

Khi bạn nhận được dữ liệu, chỉ cần thêm những dòng này

float sizeOfContent = 0; 
UIView *lLast = [yourscrollview.subviews lastObject]; 
NSInteger wd = lLast.frame.origin.y; 
NSInteger ht = lLast.frame.size.height; 
sizeOfContent = wd+ht; 
yourscrollview.contentSize = CGSizeMake(yourscrollview.frame.size.width, sizeOfContent); 

Hope this helps

+0

Làm thế nào về lỗi kịch bản? chỉ cần để nó ở đó? – paynestrike

+0

Bạn đang sử dụng tính năng tự động trả lời? – gurmandeep

+0

có Tôi đang sử dụng autolayout – paynestrike

3

Bạn nên thiết lập chế hai hơn để imageView của bạn.

  1. ngang trong container (hoặc bạn có thể nói nó trung tâm X)
  2. cố định Chiều cao

Điều thứ hai bạn có thể đặt UIView trên Scrollview với ràng buộc như thế nào, Top,leading,trailing,bottom,Horizontally in container(center x),fixed height).

Sau đó thêm bạn imageview vào chế độ xem đó. Và có thể thay đổi hạn chế của nó sau khi nhận được hình ảnh để thay đổi kích thước chiều cao và chiều rộng của nó.

Bạn có thể kết nối outlet bất kỳ ràng buộc nào và có thể thay đổi liên tục theo chương trình.

+0

Bạn có nghĩa là thêm ImageView theo chương trình? – paynestrike

+0

Bạn có thể thêm lập trình hoặc từ trình tạo giao diện. Nếu bạn đang thêm nó từ trình xây dựng giao diện thì bạn nên sử dụng các ràng buộc bắt buộc mà bạn muốn thay đổi để thay đổi kích thước nó sau khi nhận được hình ảnh từ thư viện hoặc cơ sở dữ liệu hoặc người nào khác! – Lion

+0

lý do tôi sử dụng chế độ xem cuộn là vì tôi muốn đạt được hiệu ứng thu phóng ảnh, vì vậy tôi kết nối từng ràng buộc imageview với bộ điều khiển và cập nhật giá trị giới hạn khi tải ảnh, bu có vẻ không hoạt động. – paynestrike

7

Ràng buộc hiện tại của bạn đủ để đặt kích thước nội dung, chỉ dựa trên kích thước nội dung hình ảnh nội tại và không thực sự tồn tại cho đến khi chế độ xem hình ảnh có hình ảnh.

Bạn có thể thêm giới hạn chiều rộng và chiều cao vào chế độ xem hình ảnh với giá trị mặc định và tắt các ràng buộc đó khi hình ảnh được đặt thành chế độ xem. Hoặc bạn có thể sử dụng hình ảnh trình giữ chỗ và tránh các ràng buộc bổ sung đó vì bạn luôn có kích thước nội dung nội tại cho chế độ xem hình ảnh.

3

Trình tạo giao diện người dùng Xcode có loại ràng buộc đặc biệt cho các trường hợp như vậy (khi bạn có thể thiết lập ràng buộc chỉ trong thời gian chạy). Nó được gọi là "ràng buộc chỗ dành sẵn" sẽ được loại bỏ tại thời gian xây dựng nhưng giúp loại bỏ các ràng buộc lỗi để phát triển.

Placeholder constraint

Vì vậy, giải pháp là

  1. Thêm một số hạn chế về mẫu IB và đánh dấu chúng là placeholders
  2. hạn chế cần
  3. Add trong thời gian chạy
Các vấn đề liên quan