spiegel-keyman/ios/engine/KMEI/KeymanEngine/Classes/TextViewDelegateProxy.swift
2017-11-06 12:03:08 +07:00

82 lines
3.3 KiB
Swift

//
// TextViewDelegateProxy.swift
// KeymanEngine
//
// Created by Gabriel Wong on 2017-10-06.
// Copyright © 2017 SIL International. All rights reserved.
//
// Proxies delegate messages for a TextView.
// This allows the TextView to hook into these calls while allowing a developer to still
// use the delegate as normal (albeit with a different name: 'keymanDelegate')
//
// This class is required because at the time of writing, setting a UITextView as it's
// own delegate caused an infinite loop in Apple's code, repeatedly calling the selectionDidChange callback
// See: http://lists.apple.com/archives/cocoa-dev/2010/Feb/msg01391.html
import UIKit
public protocol TextViewDelegate: UITextViewDelegate { }
class TextViewDelegateProxy: NSObject, UITextViewDelegate {
weak var keymanDelegate: TextViewDelegate?
private unowned let textView: UITextViewDelegate
init(_ textView: TextView) {
self.textView = textView
super.init()
}
// MARK: - UITextViewDelegate
// NOTE: Return values from the TextView hooks are ignored
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
_ = self.textView.textViewShouldBeginEditing?(textView)
return keymanDelegate?.textViewShouldBeginEditing?(textView) ?? true
}
func textViewDidBeginEditing(_ textView: UITextView) {
self.textView.textViewDidBeginEditing?(textView)
keymanDelegate?.textViewDidBeginEditing?(textView)
}
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
_ = self.textView.textViewShouldEndEditing?(textView)
return keymanDelegate?.textViewShouldEndEditing?(textView) ?? true
}
func textViewDidEndEditing(_ textView: UITextView) {
self.textView.textViewDidEndEditing?(textView)
keymanDelegate?.textViewDidEndEditing?(textView)
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText string: String) -> Bool {
_ = self.textView.textView?(textView, shouldChangeTextIn: range, replacementText: string)
return keymanDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: string) ?? true
}
func textViewDidChange(_ textView: UITextView) {
self.textView.textViewDidChange?(textView)
keymanDelegate?.textViewDidChange?(textView)
}
func textViewDidChangeSelection(_ textView: UITextView) {
self.textView.textViewDidChangeSelection?(textView)
keymanDelegate?.textViewDidChangeSelection?(textView)
}
@available(iOS 10.0, *)
func textView(_ textView: UITextView, shouldInteractWith text: NSTextAttachment,
in range: NSRange, interaction: UITextItemInteraction) -> Bool {
_ = self.textView.textView?(textView, shouldInteractWith: text, in: range, interaction: interaction)
return keymanDelegate?.textView?(textView, shouldInteractWith: text, in: range,
interaction: interaction) ?? true
}
@available(iOS 10.0, *)
func textView(_ textView: UITextView, shouldInteractWith url: URL,
in range: NSRange, interaction: UITextItemInteraction) -> Bool {
_ = self.textView.textView?(textView, shouldInteractWith: url, in: range, interaction: interaction)
return keymanDelegate?.textView?(textView, shouldInteractWith: url, in: range,
interaction: interaction) ?? true
}
}