2016-10-07 8 views
9

के साथ NSAttributedString में रंग विशेषता को अनदेखा किया गया है NSAttributedString में, अक्षरों की एक श्रृंखला में एक लिंक विशेषता और एक कस्टम रंग विशेषता है।NSLinkAttributeName

स्विफ्ट 2 के साथ Xcode 7 में, यह काम करता है:

enter image description here

स्विफ्ट 3 के साथ Xcode 8 में, लिंक के लिए कस्टम जिम्मेदार ठहराया रंग हमेशा (यह स्क्रीनशॉट में नारंगी होना चाहिए) नजरअंदाज कर दिया है।

enter image description here

यहाँ के परीक्षण के लिए कोड है।

स्विफ्ट 2, Xcode 7:

import Cocoa 
import XCPlayground 

let text = "Hey @user!" 

let attr = NSMutableAttributedString(string: text) 
let range = NSRange(location: 4, length: 5) 
attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orangeColor(), range: range) 
attr.addAttribute(NSLinkAttributeName, value: "http://somesite.com/", range: range) 

let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50)) 
tf.allowsEditingTextAttributes = true 
tf.selectable = true 
tf.stringValue = text 
tf.attributedStringValue = attr 

XCPlaygroundPage.currentPage.liveView = tf 

स्विफ्ट 3, Xcode 8:

import Cocoa 
import PlaygroundSupport 

let text = "Hey @user!" 

let attr = NSMutableAttributedString(string: text) 
let range = NSRange(location: 4, length: 5) 
attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: range) 
attr.addAttribute(NSLinkAttributeName, value: "http://somesite.com/", range: range) 

let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50)) 
tf.allowsEditingTextAttributes = true 
tf.isSelectable = true 
tf.stringValue = text 
tf.attributedStringValue = attr 

PlaygroundPage.current.liveView = tf 

मैं एप्पल के लिए एक बग रिपोर्ट भेज दिया है, लेकिन इस बीच में किसी के लिए एक विचार है, तो एक्सकोड 8 में एक फिक्स या वर्कअराउंड, यह बहुत अच्छा होगा।

+0

जब आप का उपयोग 'NSTextView', आप' linkTextAttributes' संपत्ति सेट करना होगा। जब एक 'NSTextField' केंद्रित होता है और संपादित किया जा सकता है, तो पाठ' NSTextView' में दिखाया गया है जो इसके 'linkTextAttributes' (डिफ़ॉल्ट नीले, रेखांकित और एक हाथ कर्सर) का उपयोग करता है। – Willeke

+0

@ विलेके धन्यवाद, दुर्भाग्य से मैंने लिंकटाक्स्ट एट्रिब्यूट को ओवरराइड करने का प्रयास कर लिया है, यह एक अच्छा समाधान है लेकिन यह जिम्मेदार स्ट्रिंग में सभी लिंक पर समान गुण लागू करता है, और मुझे अलग-अलग सेट करने में सक्षम होना चाहिए। बात यह है कि, * मेरे दूसरे प्रश्न का आपका जवाब हाल ही में काम करता है *, यहां बड़ी बड़ी बहन है कि आपने जिस सटीक कोड का उत्तर दिया है वह अब और काम नहीं करता है। :) – Moritz

+0

ओह। लिंक एक्सकोड 7 में नारंगी है। यह एक्सकोड 8 में नीला है। मैं एक रडार दाखिल कर रहा हूं ... आपको इसके साथ परेशान करने के लिए खेद है, @ विलेके ... – Moritz

उत्तर

4

Apple डेवलपर उत्तर दिया:

पता कृपया के रूप में उपलब्ध कराई गई जानकारी के आधार पर इरादा कि हमारी इंजीनियरिंग टीम इस मुद्दे कि बर्ताव करता है निर्धारित किया है।

और वे स्पष्टीकरण दें कि यह पहले से काम किया है, लेकिन अब और नहीं करता है:

दुर्भाग्य से, पिछले व्यवहारस्पष्ट नहीं था समर्थित (जिम्मेदार ठहराया स्ट्रिंग NSLinkAttributeName एक कस्टम रंग में प्रतिपादन के साथ पर्वतमाला) । यह काम करने के लिए हुआ क्योंकि एनएसटीक्स्टफाल्ड केवल फ़ील्ड एडिटर मौजूद था जब लिंक को प्रतिपादित कर रहा था; फ़ील्ड एडिटर के बिना, हम NSForegroundColorAttributeName द्वारा निर्दिष्ट रंग पर वापस आते हैं।

संस्करण 10.12 ने आईएसओ के समान डिफ़ॉल्ट लिंक उपस्थिति का उपयोग करके लिंक प्रस्तुत करने के लिए NSLayoutManager और NSTextField को अद्यतन किया। (see AppKit release notes for 10.12.)

स्थिरता को बढ़ावा देने के लिए, इच्छित व्यवहार उन श्रेणियों के लिए है जो डिफ़ॉल्ट लिंक उपस्थिति का उपयोग करके खींचे जाने के लिए लिंक (NSLinkAttributeName के माध्यम से निर्दिष्ट) का प्रतिनिधित्व करते हैं। तो वर्तमान व्यवहार अपेक्षित व्यवहार है।

(जोर मेरा)

+1

धन्यवाद! बेहद उपयोगी जानकारी। – Oleg

4

इस उत्तर NSLinkAttributeName अनदेखी कस्टम रंग जारी करने के लिए एक ठीक नहीं है, यह NSAttributedString में क्लिक करने योग्य शब्द रंगीन होने के लिए एक वैकल्पिक समाधान है।


इस समाधान हम सब पर NSLinkAttributeName का उपयोग नहीं करते, क्योंकि यह एक शैली हम नहीं चाहते बलों के साथ

इसके बजाए, हम कस्टम विशेषताओं का उपयोग करते हैं, और हम माउस क्लिक के तहत विशेषताओं का पता लगाने और तदनुसार कार्य करने के लिए NSTextField/NSTextView उपclass करते हैं।

कई बाधाएं हैं, जाहिर है: आपको mouseDown इत्यादि को ओवरराइड करने के लिए फ़ील्ड/व्यू को उपclass करने में सक्षम होना चाहिए, लेकिन एक फिक्स के इंतजार के दौरान "यह मेरे लिए काम करता है"।

theAttributedString.addAttribute("CUSTOM", value: theLink, range: theLinkRange) 
theAttributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: theLinkRange) 
theAttributedString.addAttribute(NSCursorAttributeName, value: NSCursor.arrow(), range: theLinkRange) 

लिंक के लिए रंग और सामग्री सेट है:

जब आपके NSMutableAttributedString, जहां आप एक NSLinkAttributeName सेट है | तैयारी कर रहा है, बजाय एक कस्टम कुंजी के साथ एक विशेषता के रूप में लिंक की स्थापना की। अब हमें इसे क्लिक करने योग्य बनाना है।

इसके लिए, अपने NSTextView को उपclass और mouseDown(with event: NSEvent) ओवरराइड करें।

हमें विंडो में माउस ईवेंट का स्थान मिलेगा, उस स्थान पर टेक्स्ट व्यू में वर्ण अनुक्रमणिका ढूंढें, और टेक्स्ट इंडेक्स की विशेषता स्ट्रिंग में इस अनुक्रमणिका में वर्ण के गुणों के लिए पूछें।

class MyTextView: NSTextView { 

    override func mouseDown(with event: NSEvent) { 
     // the location of the click event in the window 
     let point = self.convert(event.locationInWindow, from: nil) 
     // the index of the character in the view at this location 
     let charIndex = self.characterIndexForInsertion(at: point) 
     // if we are not outside the string... 
     if charIndex < super.attributedString().length { 
      // ask for the attributes of the character at this location 
      let attributes = super.attributedString().attributes(at: charIndex, effectiveRange: nil) 
      // if the attributes contain our key, we have our link 
      if let link = attributes["CUSTOM"] as? String { 
       // open the link, or send it via delegate/notification 
      } 
     } 
     // cascade the event to super (optional) 
     super.mouseDown(with: event) 
    } 

} 

यही है।

मेरे मामले में मुझे अलग-अलग रंगों और लिंक प्रकारों के साथ अलग-अलग शब्दों को कस्टमाइज़ करने की आवश्यकता है, इसलिए केवल एक स्ट्रिंग के रूप में लिंक को पास करने के बजाय मैं एक स्ट्रक्चर पास करता हूं जिसमें लिंक और अतिरिक्त मेटा जानकारी होती है, लेकिन विचार समान है।

यदि आपको NSTextView के बजाय NSTextField का उपयोग करना है, तो क्लिक ईवेंट स्थान ढूंढने के लिए यह थोड़ा सा कठिन है। NSTextField के अंदर NSTextView बनाने का एक समाधान है और वहां से पहले की तरह ही तकनीक का उपयोग करना है।

class MyTextField: NSTextField { 

    var referenceView: NSTextView { 
     let theRect = self.cell!.titleRect(forBounds: self.bounds) 
     let tv = NSTextView(frame: theRect) 
     tv.textStorage!.setAttributedString(self.attributedStringValue) 
     return tv 
    } 

    override func mouseDown(with event: NSEvent) { 
     let point = self.convert(event.locationInWindow, from: nil) 
     let charIndex = referenceView.textContainer!.textView!.characterIndexForInsertion(at: point) 
     if charIndex < self.attributedStringValue.length { 
      let attributes = self.attributedStringValue.attributes(at: charIndex, effectiveRange: nil) 
      if let link = attributes["CUSTOM"] as? String { 
       // ... 
      } 
     } 
     super.mouseDown(with: event) 
    } 

}