Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 检测点击图像';当UITextVIew编辑为True时,附加在NSAttributed字符串中的_Ios_Swift_Uitextview_Nsattributedstring_Nstextattachment - Fatal编程技术网

Ios 检测点击图像';当UITextVIew编辑为True时,附加在NSAttributed字符串中的

Ios 检测点击图像';当UITextVIew编辑为True时,附加在NSAttributed字符串中的,ios,swift,uitextview,nsattributedstring,nstextattachment,Ios,Swift,Uitextview,Nsattributedstring,Nstextattachment,我使用下面的方法来检测UITextView中图像上的点击 `func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool` 此方法仅在textView.isEditable=false时调用 `func textView(_ t

我使用下面的方法来检测
UITextView
中图像上的点击

`func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool`
此方法仅在
textView.isEditable=false
时调用

`func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool`
因此,我在
UITextView
上添加了
uitappesturerecognizer
,当用户点击
UITextView
中的图像时,它会调用。但在这一点上,如果
UITextView
中有多个图像,我不知道如何检测用户点击的图像。我还获得了点击的x和y位置,但不知道如何从这些位置获取文本或图像

let TapGesture = UITapGestureRecognizer(target: self, action: #selector(tapDetected(sender:)))
TapGesture.delegate = self
textView.addGestureRecognizer(TapGesture)`
我还尝试在
textView.addSubview
中添加一个视图。但我也不知道如果用户想在子视图之前或之后键入文本,我如何更改其位置,就像它的行为与
NSAttributedString image
相应地更改其位置一样

let imgRect : UIBezierPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 30, height: 30))
textView.textContainer.exclusionPaths = [imgRect]
let spacerView : UIView = UIView.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
spacerView.backgroundColor = .red
textView.addSubview(spacerView)
谁能告诉我如何在编辑过程中检测点击图像是正确的。或者任何人都知道如何在
NSAttributedString
image上添加操作(addTarget)。我还检查了iOS默认的
Notes
App,他们正在做我需要的事情。此功能背后的主要原因我想在
UiTextView
中添加附加视频缩略图选项,当用户在键入视频缩略图时,视频将自动在播放器中播放。我正在附上我从手机上录制的视频,这是我的

我需要与下面视频完全相同的功能

谢谢

import UIKit

class ViewController: UIViewController,UITextViewDelegate,UIGestureRecognizerDelegate {

    @IBOutlet var textView: UITextView!
    @IBOutlet var imageView: UIImageView!

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textView.resignFirstResponder()
        print("touchesBegan")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let TapGesture = UITapGestureRecognizer(target: self, action: #selector(tapDetected(sender:)))
        TapGesture.delegate = self
        textView.addGestureRecognizer(TapGesture)

        let imgRect : UIBezierPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 30, height: 30))
        textView.textContainer.exclusionPaths = [imgRect]
        let spacerView : UIView = UIView.init(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
        spacerView.backgroundColor = .red
        textView.addSubview(spacerView)

        textView.attributedText.addObserver(self, forKeyPath: "image", options: .new, context: nil)
        textView.attributedText.addObserver(self, forKeyPath: "image", options: .initial, context: nil)
        textView.attributedText.addObserver(self, forKeyPath: "image", options: .old, context: nil)
        textView.attributedText.addObserver(self, forKeyPath: "image", options: .prior, context: nil)
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

    @IBAction func addImage(_ sender: Any) {

        var attributedString :NSMutableAttributedString!
        attributedString = NSMutableAttributedString(attributedString:textView.attributedText)
        let textAttachment = NSTextAttachment()
        textAttachment.image = UIImage(named: "taylor")
        let oldWidth = textAttachment.image!.size.width;

        //I'm subtracting 10px to make the image display nicely, accounting
        //for the padding inside the textView

        let scaleFactor = (oldWidth / (textView.frame.size.width - 10))
        textAttachment.image = UIImage(cgImage: textAttachment.image!.cgImage!, scale: scaleFactor, orientation: .up)
        let attrStringWithImage = NSAttributedString(attachment: textAttachment)
        attributedString.append(attrStringWithImage)
        textView.attributedText = attributedString;
    }

    @objc func tapDetected(sender: UITapGestureRecognizer) {

        print("Tap On Image")
        print("Tap Location",sender.location(in: sender.view))

        guard case let senderView = sender.view, (senderView is UITextView) else {
            return
        }

        // calculate layout manager touch location
        let textView = senderView as! UITextView, // we sure this is an UITextView, so force casting it
        layoutManager = textView.layoutManager

        var location = sender.location(in: textView)
        location.x -= textView.textContainerInset.left
        location.y -= textView.textContainerInset.top

        print("location",location)

        let textContainer = textView.textContainer,
        characterIndex = layoutManager.characterIndex(for: location, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil),
        textStorage = textView.textStorage

        guard characterIndex < textStorage.length else {
            return
        }
    }


    func textViewDidChange(_ textView: UITextView) {
        print("textViewDidChange")
    }

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        print("textViewShouldBeginEditing")
        return true
    }

    func textViewDidBeginEditing(_ textView: UITextView) {
        print("textViewDidBeginEditing")
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        print("textViewDidBeginEditing")
    }

    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        print("textViewShouldEndEditing")
        return true
    }

    func textViewDidChangeSelection(_ textView: UITextView) {
        print("textViewDidChangeSelection")

        print("selectedText", textView.selectedRange.location)
        print("textView.attributedText.containsAttachments(in: textView.selectedRange",textView.attributedText.containsAttachments(in: textView.selectedRange))
        print("textView.attributedText.attributedSubstring(from: textView.selectedRange)",textView.attributedText.attributedSubstring(from: textView.selectedRange))

        let img = textView.getParts()
        for i in img {
            if let image = i as? UIImage {
                imageView.image = image
            }
        }
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("observeValueobserveValueobserveValueobserveValueobserveValue  keyPath \(String(describing: keyPath)) change \(String(describing: change)) context \(String(describing: context)) ")
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        print("textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String)")
        return true
    }


    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        print("textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool ")
        return true
    }

    func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        print("textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool")
        imageView.image = textAttachment.image
        return true
    }

    func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool {
        print("textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool")
        return true
    }
}

extension UITextView {
    func getParts() -> [AnyObject] {
        var parts = [AnyObject]()

        let attributedString = self.attributedText
        let range = self.selectedRange//NSMakeRange(0, (attributedString?.length)!)
        attributedString?.enumerateAttributes(in: range, options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (object, range, stop) in
            if object.keys.contains(NSAttributedStringKey.attachment) {
                if let attachment = object[NSAttributedStringKey.attachment] as? NSTextAttachment {
                    if let image = attachment.image {
                        parts.append(image)
                    } else if let image = attachment.image(forBounds: attachment.bounds, textContainer: nil, characterIndex: range.location) {
                        parts.append(image)
                    }
                }
            } else {
                let stringValue : String = attributedString!.attributedSubstring(from: range).string
                if (!stringValue.trimmingCharacters(in: .whitespaces).isEmpty) {
                    parts.append(stringValue as AnyObject)
                }
            }
        }
        return parts
    }
}
导入UIKit
类ViewController:UIViewController、UIExtViewDelegate、UIGestureRecognitizerDelegate{
@IBOutlet var textView:UITextView!
@IBVAR imageView:UIImageView!
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
textView.resignFirstResponder()辞职
打印(“触摸开始”)
}
重写func viewDidLoad(){
super.viewDidLoad()
让TapSirture=UITapGestureRecognizer(目标:自我,操作:#选择器(tapDetected(发送方:))
tappostate.delegate=self
textView.AddGestureRecognitor(点击手势)
设imgRect:UIBezierPath=UIBezierPath(rect:CGRect(x:0,y:0,宽度:30,高度:30))
textView.textContainer.ExclutionPath=[imgRect]
让我们来看一看:UIView=UIView.init(帧:CGRect(x:0,y:0,宽度:30,高度:30))
SpaceView.backgroundColor=.red
textView.addSubview(间隔视图)
textView.AttributeText.addObserver(self,forKeyPath:“图像”,选项:。新建,上下文:nil)
textView.AttributeText.addObserver(self,forKeyPath:“图像”,选项:。初始,上下文:nil)
textView.AttributeText.addObserver(self,forKeyPath:“图像”,选项:。旧,上下文:nil)
textView.AttributeText.addObserver(self,forKeyPath:“图像”,选项:.prior,上下文:nil)
}
func gestureRecognizer(uGestureRecognizer:UIGestureRecognizer,应与其他gestureRecognizer:UIGestureRecognizer同时识别)->Bool{
返回真值
}
@iAction func addImage(\发送方:任意){
var attributedString:NSMutableAttributedString!
attributedString=NSMutableAttributedString(attributedString:textView.attributedText)
设textAttachment=NSTextAttachment()
textAttachment.image=UIImage(名为:“taylor”)
让oldWidth=textAttachment.image!.size.width;
//我要减去10px,使图像显示得很好
//用于文本视图内的填充
设scaleFactor=(oldWidth/(textView.frame.size.width-10))
textAttachment.image=UIImage(cgImage:textAttachment.image!.cgImage!,比例:scaleFactor,方向:.up)
让attrStringWithImage=NSAttributedString(附件:textAttachment)
attributedString.append(attrStringWithImage)
textView.attributedText=attributedString;
}
@检测到objc func TAP(发送方:UITAPGESTURE识别器){
打印(“点击图像”)
打印(“点击位置”,发送者。位置(在:发送者。视图中))
保护壳让senderView=sender.view,(senderView是UITextView)else{
返回
}
//计算布局管理器触摸位置
让textView=senderView as!UITextView,//我们确定这是一个UITextView,所以强制强制转换它
layoutManager=textView.layoutManager
var location=sender.location(在:textView中)
location.x-=textView.textContainerSet.left
location.y-=textView.textContainerSet.top
打印(“位置”,位置)
设textContainer=textView.textContainer,
characterIndex=layoutManager.characterIndex(对于:位置,在:textContainer中,插入点之间的距离分段:nil),
textStorage=textView.textStorage
保护字符索引Bool{
打印(“文本视图应开始编辑”)
返回真值
}
func textViewDidBeginEditing(uTEXTVIEW:UITextView){
打印(“textViewDidBeginEditing”)
}
func textViewDidEndEditing(uTEXTVIEW:UITextView){
打印(“textViewDidBeginEditing”)
}
func textView应取消编辑(\uTEXTVIEW:UITextView)->Bool{
打印(“文本视图应取消编辑”)
返回真值
}
func textViewDidChangeSelection(textView:UITextView){
打印(“textViewDidChangeSelection”)
打印(“selectedText”,textView.selectedRange.location)
打印(“textView.AttributeText.ContainesAttachments(在:textView.selectedRange中)、textView.AttributeText.ContainesAttachments(在:textView.selectedRange中))
打印(“textView.attributedText.attributedSubstring(from:textView.selectedRange)”,textView.attributedText.attributedSubstring(from:textVie
let fullString = NSMutableAttributedString()    
let imageAttachment = NSTextAttachment()
imageAttachment.image = image

let imageAttributedString: NSMutableAttributedString = NSAttributedString(attachment: imageAttachment).mutableCopy() as! NSMutableAttributedString

let customAttribute = [ NSAttributedStringKey.imagePath: imagePath ]
imageAttributedString.addAttributes(customAttribute, range: NSRange(location: 0, length: imageAttributedString.length))

fullString.append(imageAttributedString)
    @objc func onImageTap(_ sender: UITapGestureRecognizer) {
      let textView = sender.view as! UITextView
      let layoutManager = textView.layoutManager

      // location of tap in textView coordinates
      var location = sender.location(in: textView)
      location.x -= textView.textContainerInset.left;
      location.y -= textView.textContainerInset.top;

      // character index at tap location
      let characterIndex = layoutManager.characterIndex(for: location, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

      // if index is valid 
      if characterIndex < textView.textStorage.length {

        // check if the tap location has the custom attribute
        let attributeValue = textView.attributedText.attribute(NSAttributedStringKey.imagePath, at: characterIndex, effectiveRange: nil) as? String
        if let value = attributeValue {
            print("You tapped on \(NSAttributedStringKey.imagePath) and the value is: \(value)")
        }

    }

}
@objc func tapOnImage(_ sender: UITapGestureRecognizer) {
    let textView = sender.view as! UITextView
    let layoutManager = textView.layoutManager

    var location = sender.location(in: textView)
    location.x -= textView.textContainerInset.left
    location.y -= memtextViewoView.textContainerInset.top

    let characterIndex = layoutManager.characterIndex(for: location,
                                                      in: textView.textContainer,
                                                      fractionOfDistanceBetweenInsertionPoints: nil)

    if characterIndex < textView.textStorage.length {    
        let attachment = textView.attributedText.attribute(NSAttributedStringKey.attachment,
                                                         at: characterIndex,
                                                         effectiveRange: nil) as? NSTextAttachment
        if let attachImage = attachment {
            print("tap on image: ", attachImage.image)

        }
    }
}