gpt4 book ai didi

ios - 当我在那个 swift ios 上绘制时,ImageView 会改变坐标

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:28:44 24 4
gpt4 key购买 nike

我正在关注 this tutorial ,首先当应用程序启动时一切正常 imagView 设置在我设置的位置。但问题是,当我开始在 imageView 上绘制时,imageView 的大小会调整为不明确的坐标,并且它会扩大并占用太多空间导致不明确的 View ,即使我已经设置了自动布局。可能是我遗漏了什么,这里是代码:

import UIKit
import CoreImage

class ViewController: UIViewController {

let imageNameIs = "BradPitImage"
var lastPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false

@IBOutlet weak var tempImageView: UIImageView!
var tempImageViewtemp : UIImageView = UIImageView()

@IBOutlet weak var resetButton: UIButton!
@IBOutlet weak var saveButton: UIButton!

@IBAction func resetAct(_ sender: Any) {
tempImageView.image = nil
tempImageView.image = UIImage(named: imageNameIs)
}

override func viewDidLoad() {
super.viewDidLoad()
self.tempImageView.image = UIImage(named: imageNameIs)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = false
if let touch = touches.first {
lastPoint = touch.location(in: self.tempImageView)//view)
}
}

func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
// 1
UIGraphicsBeginImageContext(view.frame.size)//(tempImageView.frame.size) makes lines coluored of image
let context = UIGraphicsGetCurrentContext()
tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height))

// 3
context!.move(to: fromPoint)
context!.addLine(to: toPoint)
context!.setLineCap(.round)
context!.setLineWidth(brushWidth)
context!.setStrokeColor(red: red, green: green, blue: blue, alpha: 1)
context!.setBlendMode(.normal)

// 4
context!.strokePath()
//CGContextStrokePath(context!)

// 5
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
tempImageView.alpha = opacity
UIGraphicsEndImageContext()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {
let currentPoint = touch.location(in: view)
drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)
// 7
lastPoint = currentPoint
}
}

func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
// 6
swiped = true
if let touch = touches.first as? UITouch {
let currentPoint = touch.location(in: view)
drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)
// 7
lastPoint = currentPoint
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
//draw a single point
drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
}
UIGraphicsBeginImageContext(tempImageViewtemp.frame.size)
tempImageViewtemp.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: 1)
tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: opacity)
tempImageViewtemp.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
}

图片如下:

1) 何时启动

enter image description here

2)当我开始画画的时候

enter image description here

**根据DonMag的回答更新坐标仍然不明确**

它仅适用于纵向,问题是当我使用横向模式并开始绘图时,图像尺寸缩小到顶部并且底部越来越宽,然后我使用纵向模式然后图像从顶部变为中心底部越窄,我根据您的代码添加了新的屏幕截图

1) 第一次从纵向到横向:

enter image description here

2) 当我开始绘图时,它缩小了图像并且绘图变得模糊

enter image description here

现在从横向启动时看起来像这样并且绘图不会减少也不会产生任何模糊:

enter image description here

但是当转向肖像图像时会像这样缩小

enter image description here

最佳答案

一些事情...

  1. 您似乎已将 ImageView 设置为 Aspect Fit scale。这意味着您的图像与 ImageView 本身的大小不同。

  2. 您混合了 ImageView 和 Root View 的帧大小。

这是您的代码,稍作修改。查看 //--- 指示的注释。您应该能够替换当前代码并按原样运行它:

import UIKit
import CoreImage

extension UIView {
// return content of view as a UIImage
// can be used to get a copy of the rendered image view
// e.g. the result of scaling setting

func asImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
}

}

class ViewController: UIViewController {

let imageNameIs = "BradPitImage"
var lastPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false

@IBOutlet weak var tempImageView: UIImageView!
var tempImageViewtemp : UIImageView = UIImageView()

// ---
// --- this will hold a copy of the resized image (for reset)
var resizedImage: UIImage!

@IBOutlet weak var resetButton: UIButton!
@IBOutlet weak var saveButton: UIButton!

@IBAction func resetAct(_ sender: Any) {
// ---
// --- reset using the resized image from viewDidAppear
tempImageView.image = resizedImage
}

override func viewDidLoad() {
super.viewDidLoad()
self.tempImageView.image = UIImage(named: imageNameIs)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

// ---
// --- create a resized copy of the original image
// --- (handles aspect fit scale)
resizedImage = tempImageView.asImage()
tempImageView.image = resizedImage

}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = false
if let touch = touches.first {
// ---
// --- get point ** in tempImageView **
lastPoint = touch.location(in: self.tempImageView) //view)
}
}

func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
// 1

// ---
// --- get the bounds of tempImageView
let rect = tempImageView.bounds

// ---
// --- use the bounds for the image context size
UIGraphicsBeginImageContext(rect.size)

let context = UIGraphicsGetCurrentContext()

// ---
// --- draw the image into the bounds rect
tempImageView.image?.draw(in: rect)

// 3
context!.move(to: fromPoint)
context!.addLine(to: toPoint)
context!.setLineCap(.round)
context!.setLineWidth(brushWidth)
context!.setStrokeColor(red: red, green: green, blue: blue, alpha: 1)
context!.setBlendMode(.normal)

// 4
context!.strokePath()
//CGContextStrokePath(context!)

// 5
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
tempImageView.alpha = opacity
UIGraphicsEndImageContext()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {

// ---
// --- get point ** in tempImageView **
let currentPoint = touch.location(in: self.tempImageView)

drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)

// 7
lastPoint = currentPoint
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
//draw a single point
drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
}

// ---
// don't know what you're doing with tempImageViewtemp,
// but you probably want to change the sizing here to match elsewhere
UIGraphicsBeginImageContext(tempImageViewtemp.frame.size)
tempImageViewtemp.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: 1)
tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: opacity)
tempImageViewtemp.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
}

编辑:

这里有一种略有不同的方法,可以让您在自己的道路上走得更远。

不是更改图像,而是更改 imageView 的大小以匹配图像的比例。

Storyboard布局:

enter image description here

ImageView 在白色父 View 中保持居中的约束,并且将限制其宽度和高度,保持比例(纵横比)。

白色 View 有限制,以保持其大小/位于按钮上方。

结果 - 纵向,左眼画了一个圆圈:

enter image description here

结果 - 设备旋转到横向,右眼周围画了另一个圆圈:

enter image description here

您还会在代码/注释中注意到“brushWidth”必须根据图像高度进行调整...仅使用 10 磅,因为当图像较短时宽度会导致“较粗”的线条(景观)。

代码如下:

//
// DrawOnViewController.swift
//
// Created by Don Mag on 11/7/18.
//

import UIKit

extension NSLayoutConstraint {
/**
Change multiplier constraint

- parameter multiplier: CGFloat
- returns: NSLayoutConstraint
*/
func setMultiplier(multiplier:CGFloat) -> NSLayoutConstraint {

NSLayoutConstraint.deactivate([self])

let newConstraint = NSLayoutConstraint(
item: firstItem as Any,
attribute: firstAttribute,
relatedBy: relation,
toItem: secondItem,
attribute: secondAttribute,
multiplier: multiplier,
constant: constant)

newConstraint.priority = priority
newConstraint.shouldBeArchived = self.shouldBeArchived
newConstraint.identifier = self.identifier

NSLayoutConstraint.activate([newConstraint])
return newConstraint
}
}

class DrawOnViewController: UIViewController {

let imageNameIs = "BradPitImage"
var lastPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false

@IBOutlet weak var tempImageView: UIImageView!
var tempImageViewtemp : UIImageView = UIImageView()

// ---
// --- this will hold a reference to the image view's aspect ratio constraint
@IBOutlet var imageViewAspectRatioConstraint: NSLayoutConstraint!

// ---
// --- this will be used to allow "brushWidth" to remain
// --- constant when device is rotated
var loadedImageHeight: CGFloat = 0.0

// ---
// --- this will be the "brushWidth" relative to
// --- to the image's originial height
var adjustedBrushWidth: CGFloat = 0.0

@IBOutlet weak var resetButton: UIButton!
@IBOutlet weak var saveButton: UIButton!

@IBAction func resetAct(_ sender: Any) {
if let img = UIImage(named: imageNameIs) {
// ---
// --- reset the imageView's image
tempImageView.image = img
}
}

override func viewDidLoad() {
super.viewDidLoad()

if let img = UIImage(named: imageNameIs) {

let imgSize = img.size

// ---
// --- calculate the aspect ratio of the image
let ratio = imgSize.width / imgSize.height

// ---
// --- change the image view's aspect ratio to match the image
imageViewAspectRatioConstraint = imageViewAspectRatioConstraint.setMultiplier(multiplier: ratio)

// ---
// --- save original image height for brushWidth adjustment
loadedImageHeight = imgSize.height

// ---
// --- set the imageView's image
self.tempImageView.image = img

}

}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

// ---
// --- calculate brushWidth relative to image height scaled to image view height
adjustedBrushWidth = brushWidth * loadedImageHeight / tempImageView.frame.height
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = false
if let touch = touches.first {
// ---
// --- get point ** in tempImageView **
lastPoint = touch.location(in: self.tempImageView)
}
}

func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
// 1

// ---
// --- get the bounds of tempImageView
let rect = tempImageView.bounds

// ---
// --- use the bounds for the image context size
UIGraphicsBeginImageContext(rect.size)

let context = UIGraphicsGetCurrentContext()

// ---
// --- draw the image into the bounds rect
tempImageView.image?.draw(in: rect)

// 3
context!.move(to: fromPoint)
context!.addLine(to: toPoint)
context!.setLineCap(.round)

// ---
// --- set line width proportional to current imageView height
// --- use adjustedBrushWidth set in viewDidAppear
// context!.setLineWidth(brushWidth * rect.height / loadedImageHeight)
context!.setLineWidth(adjustedBrushWidth * rect.height / loadedImageHeight)

context!.setStrokeColor(red: red, green: green, blue: blue, alpha: 1)
context!.setBlendMode(.normal)

// 4
context!.strokePath()
//CGContextStrokePath(context!)

// 5
tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
tempImageView.alpha = opacity
UIGraphicsEndImageContext()
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {

// ---
// --- get point ** in tempImageView **
let currentPoint = touch.location(in: self.tempImageView)

drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)

// 7
lastPoint = currentPoint
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
//draw a single point
drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
}

// ---
// don't know what you're doing with tempImageViewtemp,
// but you probably want to change the sizing here to match elsewhere
// UIGraphicsBeginImageContext(tempImageViewtemp.frame.size)
// tempImageViewtemp.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: 1)
// tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: .normal, alpha: opacity)
// tempImageViewtemp.image = UIGraphicsGetImageFromCurrentImageContext()
// UIGraphicsEndImageContext()
}
}

这是具有所需约束的 Storyboard:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="bvb-cu-Gcn">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Draw On View Controller-->
<scene sceneID="b4T-Zn-uEk">
<objects>
<viewController id="bvb-cu-Gcn" customClass="DrawOnViewController" customModule="SW4Temp" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="fif-yb-Cf8">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GU5-HP-5fd">
<rect key="frame" x="8" y="28" width="359" height="593"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="1MQ-UT-8dQ">
<rect key="frame" x="0.5" y="117.5" width="358.5" height="358.5"/>
<color key="backgroundColor" red="1" green="0.1857388616" blue="0.57339501380000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="1MQ-UT-8dQ" secondAttribute="height" multiplier="1:1" id="xD6-8c-1AI"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="1MQ-UT-8dQ" firstAttribute="height" secondItem="GU5-HP-5fd" secondAttribute="height" priority="750" id="14p-DB-cE1"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="1MQ-UT-8dQ" secondAttribute="bottom" id="9A8-ey-EzV"/>
<constraint firstItem="1MQ-UT-8dQ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="GU5-HP-5fd" secondAttribute="leading" id="DbB-Mv-lEx"/>
<constraint firstItem="1MQ-UT-8dQ" firstAttribute="top" relation="greaterThanOrEqual" secondItem="GU5-HP-5fd" secondAttribute="top" id="Eq0-pn-RKN"/>
<constraint firstItem="1MQ-UT-8dQ" firstAttribute="centerY" secondItem="GU5-HP-5fd" secondAttribute="centerY" id="d9A-Un-06B"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="1MQ-UT-8dQ" secondAttribute="trailing" id="dDp-HC-4pn"/>
<constraint firstItem="1MQ-UT-8dQ" firstAttribute="centerX" secondItem="GU5-HP-5fd" secondAttribute="centerX" id="mqJ-4L-wQR"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QmC-N4-hsp">
<rect key="frame" x="20" y="629" width="39" height="30"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Reset"/>
<connections>
<action selector="resetAct:" destination="bvb-cu-Gcn" eventType="touchUpInside" id="5ug-cY-v6A"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BWU-rw-ePF">
<rect key="frame" x="321" y="629" width="34" height="30"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Save"/>
<connections>
<action selector="resetAct:" destination="bvb-cu-Gcn" eventType="touchUpInside" id="JkQ-M7-brY"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sia-an-mGC">
<rect key="frame" x="168.5" y="629" width="37" height="30"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Color"/>
</button>
</subviews>
<color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="mdN-5j-gOT" firstAttribute="bottom" secondItem="sia-an-mGC" secondAttribute="bottom" constant="8" id="33Q-9r-cik"/>
<constraint firstItem="mdN-5j-gOT" firstAttribute="bottom" secondItem="BWU-rw-ePF" secondAttribute="bottom" constant="8" id="9Xw-wi-cSH"/>
<constraint firstItem="mdN-5j-gOT" firstAttribute="trailing" secondItem="BWU-rw-ePF" secondAttribute="trailing" constant="20" id="Bwp-Uu-Qt7"/>
<constraint firstItem="GU5-HP-5fd" firstAttribute="top" secondItem="mdN-5j-gOT" secondAttribute="top" constant="8" id="E63-DW-lHC"/>
<constraint firstItem="mdN-5j-gOT" firstAttribute="trailing" secondItem="GU5-HP-5fd" secondAttribute="trailing" constant="8" id="GDF-yb-Zhr"/>
<constraint firstItem="GU5-HP-5fd" firstAttribute="leading" secondItem="mdN-5j-gOT" secondAttribute="leading" constant="8" id="Pw9-SO-lkd"/>
<constraint firstItem="mdN-5j-gOT" firstAttribute="bottom" secondItem="QmC-N4-hsp" secondAttribute="bottom" constant="8" id="TKU-Ht-CmQ"/>
<constraint firstItem="QmC-N4-hsp" firstAttribute="leading" secondItem="mdN-5j-gOT" secondAttribute="leading" constant="20" id="Uwc-k4-TP4"/>
<constraint firstItem="QmC-N4-hsp" firstAttribute="top" secondItem="GU5-HP-5fd" secondAttribute="bottom" constant="8" id="ute-8t-Q2P"/>
<constraint firstItem="sia-an-mGC" firstAttribute="centerX" secondItem="fif-yb-Cf8" secondAttribute="centerX" id="zXd-nm-Goa"/>
</constraints>
<viewLayoutGuide key="safeArea" id="mdN-5j-gOT"/>
</view>
<connections>
<outlet property="imageViewAspectRatioConstraint" destination="xD6-8c-1AI" id="KWT-aA-gtN"/>
<outlet property="tempImageView" destination="1MQ-UT-8dQ" id="brX-iu-UgX"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="zoz-eV-W9h" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="48.799999999999997" y="624.73763118440786"/>
</scene>
</scenes>
</document>

关于ios - 当我在那个 swift ios 上绘制时,ImageView 会改变坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53169386/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com