【问题标题】:Swift 3 - UIImageView image gets shrunkSwift 3 - UIImageView 图像缩小
【发布时间】:2018-01-16 08:45:43
【问题描述】:

这是为转场做准备的代码,然后从转场中解脱出来。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "toTossImageVC" {
        let dvc = segue.destination as! TossImageViewController
        dvc.displayedImage = tossPhoto2.image
    }
}

@IBAction func unwindToTossVC(unwindSegue: UIStoryboardSegue) {

    let dvc = unwindSegue.source as! TossImageViewController
    self.tossPhoto2.image = dvc.displayedImage
}

可以看出,我在准备中将图像传递给目标 VC,然后在 unwind 方法中检索该图像的更新版本(用户可以在目标 VC 中标记图像)。

self.tossPhoto2 是一个 UIImage 对象,它的 contentMode 在 Interface Builder 中设置为 scaleToFill。我的问题是,当我展开并将 tossPhoto2 的图像分配给 dvc.displayedImage 时,它​​会严重缩小。在对图像进行分割和标记之前:

BeforePhotoFine

然后,当我们在用标签标记照片后返回这个 VC 时,这是经过可怕缩小的照片:

AfterPhotoShrunk

在 StackOverflow 和其他地方搜索了几个小时后,解决问题的最佳建议是将 contentMode 设置为 .scaleAspectFit 但这不起作用(而且我想按照 Interface Builder 中的定义将其保留为 scaleToFill )。

任何想法为什么会发生这种情况以及如何解决这个问题?如果有帮助,这是 TossImageViewController 中的代码,但我看不出我是如何无意中缩小图像的。这可以允许用户在图像上添加标签(实现为 UILabel)。

class TossImageViewController: UIViewController, UINavigationControllerDelegate, UIGestureRecognizerDelegate {
@IBOutlet var tossImage: UIImageView!
var displayedImage: UIImage!
let ac = UIAlertController(title: "Select Toss Type", message: nil, preferredStyle: .actionSheet)
var selectedTossType = String()
var touchPoint: CGPoint!


override func viewDidLoad() {
    super.viewDidLoad()
    tossImage.image = displayedImage

    self.tabBarController?.tabBar.isHidden = true

    let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    self.view.addGestureRecognizer(gestureRecognizer)

    // Set up the action sheet picker
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    ac.addAction(cancelAction)
    let trashAction = UIAlertAction(title: "Trash", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Trash"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 80)
        print("Trash tag")
    })
    ac.addAction(trashAction)
    let sinkAction = UIAlertAction(title: "Sink Disposal", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Sink Disposal"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 120)
    })
    ac.addAction(sinkAction)
    let saveAction = UIAlertAction(title: "Save for Later", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Save for Later"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 140)
    })
    ac.addAction(saveAction)
    let animalAction = UIAlertAction(title: "Animal", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Animal"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 80)
    })
    ac.addAction(animalAction)
    let sharingAction = UIAlertAction(title: "Sharing", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Sharing"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 80)
    })
    ac.addAction(sharingAction)
    let compostAction = UIAlertAction(title: "Compost", style: .destructive, handler: {(action) -> Void in
        self.selectedTossType = "Compost"
        // Write the selected toss type where the tap happened
        self.displayedImage = self.textToImage(drawText: self.selectedTossType as NSString, inImage: self.displayedImage, atPoint: self.touchPoint, labelWidth: 80)
    })
    ac.addAction(compostAction)

}

override func viewWillDisappear(_ animated: Bool) {
    self.tabBarController?.tabBar.isHidden = false
}

@IBAction func cancel(_ sender: Any) {
    navigationController!.popViewController(animated: true)
}

func textToImage(drawText text: NSString, inImage image: UIImage, atPoint point: CGPoint, labelWidth: CGFloat) -> UIImage {

    let label = UILabel(frame: CGRect(x: (point.x - labelWidth/2), y: point.y, width: labelWidth, height: 20))
    label.textColor = .red
    label.shadowColor = .yellow
    label.text = text as String
    label.textAlignment = .center
    self.view.addSubview(label)

    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
    view.layer.render(in: UIGraphicsGetCurrentContext()!)
    let taggedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return taggedImage!
}

【问题讨论】:

  • contentMode 不会 改变图像 - 它只是改变它的显示方式。我猜TossImageViewController 中的某些东西正在修改图像,并且在您没有故意这样做的情况下,正在创建一个 small 版本,然后将其返回。
  • 了解 contentMode。根据您的提示,我在执行此问题的整个过程中(在两个 VC 之间)检查了 image.size,它从未改变:3000 宽到 2002 年高。仍在挖掘答案。如果有帮助,我可以分享 TossImageViewController 中的代码。

标签: ios swift3 uiimageview


【解决方案1】:

好的 - 看起来这就是问题所在......

您的TossImageViewController 中有一个UIImageView - 我不知道它的大小,但假设它是 300x300。你设置它的.image = displayedImage。到目前为止,一切都很好...您会看到您的图像已缩放以适合屏幕大小。

接下来,在用户交互之后,您调用textToImage(...),我您正试图将文本绘制到原始图像上?如果是这样,那不是正在发生的事情。

相反,您将UILabel 添加到self.view,创建3000 x 2002 的图形上下文,然后返回UIGraphicsGetImageFromCurrentImageContext() ...但该图像是当前视图-可能是750 x 1334 和坐在 Context 的左上角。

您需要做的是:

a) 创建一个3000 x 2002 UIView,将图像添加到 UIImageView 作为该视图的子视图,然后将 UILabel(相对于大图像的大小)添加为另一个子视图。然后从 that 上下文中获取图像。或者……

b) 使用 Context 和图像 drawInRect 和字符串 drawInRect 函数。

这篇文章有一些讨论和解决方案(包括 Obj-C 和 Swift):How to write text on image in Objective-C (iOS)?

【讨论】:

  • 谢谢!这让我克服了困难——我最终关注了你提供的链接中的讨论,我现在(非常接近)得到我正在寻找的确切行为。我真的很感激!
  • DonMag - 按照您链接到的 SO 帖子中的代码,我可以在不缩小图像的情况下让事情正常工作,一切都很好。但是现在文本没有显示在用户点击的位置,正如我在这篇文章中描述的那样:stackoverflow.com/questions/45580224/…。关于为什么会发生这种情况的任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 2015-07-12
  • 2012-08-13
  • 1970-01-01
相关资源
最近更新 更多