objective c - NSRange에서 UITextRange 만들기




objective-c ios5 (4)

NSRange 대신 swifty Range<String.Index> 를 사용하여 UITextView 확장으로서의 Nicolas Bachschmidt의 대답 중 Swift 4 :

extension UITextView {
    func frame(ofTextRange range: Range<String.Index>?) -> CGRect? {
        guard let range = range else { return nil }
        let length = range.upperBound.encodedOffset-range.lowerBound.encodedOffset
        guard
            let start = position(from: beginningOfDocument, offset: range.lowerBound.encodedOffset),
            let end = position(from: start, offset: length),
            let txtRange = textRange(from: start, to: end)
            else { return nil }
        let rect = self.firstRect(for: txtRange)
        return self.convert(rect, to: textInputView)
    }
}

가능한 사용 :

guard let rect = textView.frame(ofTextRange: text.range(of: "awesome")) else { return }
let awesomeView = UIView()
awesomeView.frame = rect.insetBy(dx: -3.0, dy: 0)
awesomeView.layer.borderColor = UIColor.black.cgColor
awesomeView.layer.borderWidth = 1.0
awesomeView.layer.cornerRadius = 3
self.view.insertSubview(awesomeView, belowSubview: textView)

텍스트 뷰에서 다른 범위의 픽셀 프레임을 찾아야합니다. - (CGRect)firstRectForRange:(UITextRange *)range; 그것을하기 위해. 그러나 UITextRange 실제로 만드는 방법을 찾을 수 없습니다.

기본적으로 이것은 내가 찾고있는 것입니다 :

- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {

    UITextRange*range2 = [UITextRange rangeWithNSRange:range]; //DOES NOT EXIST 
    CGRect rect = [textView firstRectForRange:range2];
    return rect;
}

Apple은 UITextInput 프로토콜을 채택하기 위해 UITextRangeUITextPosition 을 하위 클래스 UITextRange 해야한다고 말합니다. 나는 그렇게하지 않는다. 그러나 나는 어쨌든, doc의 예제 코드를 따르고 firstRectForRange 서브 클래스를 전달하여 충돌을 일으켰다.

다른 색깔의 UILablesUILables 에 추가하는 더 쉬운 방법이 있다면 말해주십시오. 나는 TRUE로 설정된 content editable UIWebView를 사용하여 시도했지만 JS와 통신하는 것을 좋아하지는 않으며 색칠 만하면된다.

미리 감사드립니다.


그것은 매우 우스꽝 스럽습니다. 간단한 "해결 방법"은 범위를 선택하고 (NSRange를 허용) selectedTextRange (UITextRange를 반환)를 읽는 것입니다.

- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {
    textView.selectedRange = range;
    UITextRange *textRange = [textView selectedTextRange]; 
    CGRect rect = [textView firstRectForRange:textRange];
    return rect;
}

textView가 첫 번째 응답자가 아니더라도 나를 위해 일했습니다.

선택 항목을 계속 유지하지 않으려면 selectedRange :

textView.selectedRange = NSMakeRange(0, 0);

... 또는 현재 선택 사항을 저장하고 나중에 복원하십시오.

NSRange oldRange = textView.selectedRange;
// do something
// then check if the range is still valid and
textView.selectedRange = oldRange;

제목 질문에, 여기 NSRange에서 UITextRange를 생성하는 Swift 2 확장 이 있습니다.

UITextRange의 유일한 이니셜 라이저는 UITextInput 프로토콜의 인스턴스 메서드이므로 UITextField 또는 UITextView 와 같은 UITextInput을 전달해야합니다.

extension NSRange {
    func toTextRange(textInput textInput:UITextInput) -> UITextRange? {
        if let rangeStart = textInput.positionFromPosition(textInput.beginningOfDocument, offset: location),
            rangeEnd = textInput.positionFromPosition(rangeStart, offset: length) {
            return textInput.textRangeFromPosition(rangeStart, toPosition: rangeEnd)
        }
        return nil
    }
}

여기에 설명되어 있습니다.

UITextRange 객체는 텍스트 컨테이너의 문자 범위를 나타냅니다. 즉, 텍스트 입력 객체를 지원하는 문자열에서 시작 색인과 종료 색인을 식별합니다.

UITextInput 프로토콜을 채택한 클래스는 클래스가 관리하는 텍스트 내의 범위를 나타내는 사용자 정의 UITextRange 객체를 만들어야합니다. 범위의 시작 및 끝 인덱스는 UITextPosition 객체로 나타냅니다. 텍스트 시스템은 텍스트 레이아웃 정보를 전달하기 위해 UITextRange 및 UITextPosition 객체를 모두 사용합니다. NSRange와 같은 기본 유형이 아닌 텍스트 범위에 객체를 사용하는 데에는 두 가지 이유가 있습니다.

일부 문서에는 중첩 요소 (예 : HTML 태그 및 포함 된 개체)가 포함되어 있으며 표시되는 텍스트에서 절대 위치와 위치를 모두 추적해야합니다.

iPhone 텍스트 시스템이 기반으로하는 WebKit 프레임 워크는 텍스트 색인 및 오프셋이 객체로 표현되어야합니다.

UITextInput 프로토콜을 채택하는 경우 사용자 지정 UITextRange 하위 클래스와 사용자 지정 UITextPosition 하위 클래스를 만들어야합니다.

예를 들어 그 출처 에서와 같이







nsrange