আমি কীভাবে সুইফটে একটি ইউআইটিেক্সটভিউয়ের ভিতরে স্থানধারক পাঠ্য যুক্ত করতে পারি?


316

আমি একটি অ্যাপ্লিকেশন তৈরি করছি যা একটি ব্যবহার করে UITextView। এখন আমি টেক্সট ভিউতে কোনও পাঠ্যক্ষেত্রের জন্য ঠিক করতে পারে এমন প্লেসহোল্ডারের অনুরূপ প্লেস ভিউর থাকতে চাই। আপনি কীভাবে সুইফট ব্যবহার করে এটি সম্পাদন করবেন?


ইউআইটিেক্সটভিউয়ের সাথে আইওএস বিকাশের এটি একটি পুরানো সমস্যা। আমি এখানে উল্লিখিত মত সাবক্লাস লিখেছি: stackoverflow.com/a/1704469/1403046 । সুবিধাটি হ'ল আপনার এখনও একটি প্রতিনিধি থাকতে পারে পাশাপাশি যুক্তিকে পুনরায় বাস্তবায়ন না করে একাধিক জায়গায় ক্লাসটি ব্যবহার করতে পারেন।
সিজওয়र्थ

প্রকল্পের সুইফ্ট ব্যবহার করার সময় আমি কীভাবে আপনার সাবক্লাস ব্যবহার করব। ব্রিজ ফাইল ব্যবহার করছেন?
স্টিভেনআর

আপনি এটি করতে পারেন, বা এটি সুইফটে পুনরায় প্রয়োগ করতে পারেন। উত্তরের কোডটি এটির চেয়ে বেশি দীর্ঘ is মূল পয়েন্টটি আপনি যে পদ্ধতিতে যুক্ত লেবেলটি দেখান / লুকিয়ে রাখেন সেটি পাঠ্য পরিবর্তনের সময় আপনাকে জানানো হয়।
সিজওয়र्थ

আপনি গিটহাব থেকে ইউআইফ্লাট লেবেলটেক্সটভিউ নমুনা ব্যবহার করতে পারেন। লেখার সময় শীর্ষে এই অবস্থানের স্থানধারক। সত্যিই আকর্ষণীয় এক! github.com/ArtSabintsev/UIFloatLabelTextView
জয়প্রকাশ দুবে

2
সত্যিকার অর্থে, এটি সম্পাদন করার সহজতম উপায় হ'ল একটি কাস্টম পাঠ্য ভিউ এবং কোনও পাঠ্য উপস্থিত না থাকায় পাঠ্যধারীর উপরে আঁকানো কেবল স্থানধারক পাঠ্য যুক্ত করা .... এখনও অবধি অন্য উত্তরগুলি এর একদম অতিরিক্ত জটিল জটিল সংস্করণ যা সমস্যাযুক্ত জড়িত রাষ্ট্র পরিচালনার (যখন পাঠ্য থাকা উচিত / থাকা উচিত / থাকা না
থাকায়

উত্তর:


647

সুইফট 4-র জন্য আপডেট হয়েছে

UITextViewসহজাতভাবে কোনও স্থানধারকের সম্পত্তি নেই তাই আপনাকে UITextViewDelegateপদ্ধতিগুলি ব্যবহার করে একটি প্রোগ্রাম তৈরি করতে এবং ম্যানিপুলেট করতে হবে । আমি পছন্দসই আচরণের উপর নির্ভর করে নীচের সমাধান # 1 বা # 2 ব্যবহার করার পরামর্শ দিচ্ছি।

দ্রষ্টব্য: যে কোনও সমাধানের UITextViewDelegateজন্য, শ্রেণিতে যুক্ত করুন এবং textView.delegate = selfপাঠ্য দর্শনের প্রতিনিধি পদ্ধতিগুলি ব্যবহার করতে সেট করুন ।


সমাধান # 1 - আপনি যদি প্লেসোল্ডারটি পাঠ্য দর্শনটি বাছাইয়ের সাথে সাথে প্লেসোল্ডার অদৃশ্য হয়ে যেতে চান:

UITextViewস্থানধারক পাঠ্য ধারণ করতে প্রথমে সেটটি সেট করুন এবং কোনও স্থানধারক পাঠ্যের চেহারা অনুকরণ করতে এটি হালকা ধূসর রঙে সেট UITextFieldকরুন। হয় viewDidLoadবা পাঠ্য দৃশ্যের তৈরির উপর এটি করুন।

textView.text = "Placeholder"
textView.textColor = UIColor.lightGray

তারপরে ব্যবহারকারী যখন পাঠ্য দর্শনটি সম্পাদনা করতে শুরু করেন, যদি পাঠ্য দৃশ্যে কোনও স্থানধারক থাকে (যেমন যদি এর পাঠ্যের রঙ হালকা ধূসর হয়) স্থানধারক পাঠ্যটি সাফ করুন এবং ব্যবহারকারীর প্রবেশের জন্য টেক্সট রঙটি কালোতে সেট করুন।

func textViewDidBeginEditing(_ textView: UITextView) {
    if textView.textColor == UIColor.lightGray {
        textView.text = nil
        textView.textColor = UIColor.black
    }
}

তারপরে ব্যবহারকারী যখন পাঠ্য প্রদর্শনের সম্পাদনা শেষ করে এবং এটি প্রথম প্রতিক্রিয়াকারী হিসাবে পদত্যাগ করে, পাঠ্য দর্শনটি ফাঁকা থাকলে স্থানধারক পাঠ্যটিকে পুনরায় যুক্ত করে এবং এর রঙ হালকা ধূসরতে সেট করে এর স্থানধারকটিকে পুনরায় সেট করুন।

func textViewDidEndEditing(_ textView: UITextView) {
    if textView.text.isEmpty {
        textView.text = "Placeholder"
        textView.textColor = UIColor.lightGray
    }
}

সমাধান # 2 - আপনি যদি পাঠক দর্শনটি ফাঁকা থাকাকালীন স্থানধারকটি প্রদর্শন করতে চান, এমনকি পাঠ্য দর্শনটি নির্বাচিত হলেও:

প্রথমে স্থানধারকটি সেট করুন viewDidLoad:

textView.text = "Placeholder"
textView.textColor = UIColor.lightGray

textView.becomeFirstResponder()

textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)

(দ্রষ্টব্য: ওপি ভিউ লোড হওয়ার সাথে সাথেই পাঠ্যদর্শনটি নির্বাচন করতে চেয়েছিল, তাই আমি উপরের কোডের মধ্যে পাঠ্য দর্শন নির্বাচনটি অন্তর্ভুক্ত করেছি If যদি এটি আপনার পছন্দসই আচরণ না হয় এবং আপনি না চান তবে ভিউ লোডের উপরে পাঠ্য দর্শনটি নির্বাচন করা হয়েছে, উপরের কোড অংশ থেকে শেষ দুটি লাইন সরান।)

তারপরে এই shouldChangeTextInRange UITextViewDelegateপদ্ধতিটি ব্যবহার করুন :

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    // Combine the textView text and the replacement text to
    // create the updated text string
    let currentText:String = textView.text
    let updatedText = (currentText as NSString).replacingCharacters(in: range, with: text)

    // If updated text view will be empty, add the placeholder
    // and set the cursor to the beginning of the text view
    if updatedText.isEmpty {

        textView.text = "Placeholder"
        textView.textColor = UIColor.lightGray

        textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
    }

    // Else if the text view's placeholder is showing and the
    // length of the replacement string is greater than 0, set 
    // the text color to black then set its text to the
    // replacement string
     else if textView.textColor == UIColor.lightGray && !text.isEmpty {
        textView.textColor = UIColor.black
        textView.text = text
    }

    // For every other case, the text should change with the usual
    // behavior...
    else {
        return true
    }

    // ...otherwise return false since the updates have already
    // been made
    return false
}

এবং textViewDidChangeSelectionস্থানধারকের দৃশ্যমান অবস্থায় ব্যবহারকারীকে কার্সারের অবস্থান পরিবর্তন করতে বাধা দিতে বাস্তবায়ন করুন । (দ্রষ্টব্য: textViewDidChangeSelectionভিউ লোড হওয়ার আগে ডাকা হয় তাই উইন্ডোটি দৃশ্যমান হলে কেবল পাঠ্য দৃশ্যের রঙ পরীক্ষা করুন):

func textViewDidChangeSelection(_ textView: UITextView) {
    if self.view.window != nil {
        if textView.textColor == UIColor.lightGray {
            textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
        }
    }
}

5
হাই, আপনার টেক্সটভিউর প্রতিনিধি হিসাবে আপনি নিজের দর্শন নিয়ন্ত্রককে সেট করেছেন তা নিশ্চিত করুন । আপনি আপনার পাঠ্য ভিউ থেকে আপনার ভিউকন্ট্রোলারের কাছে একটি আউটলেট তৈরি করে এটি অর্জন করতে পারেন। তারপরে ব্যবহার করুন yourTextField.delegate = self। আপনি যদি এটি না করেন তবে textViewDidBeginEditingএবং textViewDidEndEditingকার্যগুলি কার্যকর হবে না।
উজ্জ্বল-নাধানী

2
কোডটি সংকলন করছে না, আমি হিসাবে একটি ত্রুটি করছি Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
আইপেটর

4
আমি সমাধানটি খুঁজে পেয়েছি এবং আমি সংশোধিত কোড @ iPeter সংযুক্ত করব। বর্তমান টেক্সট NSString formant হতে হবে: let currentText = textView.text as NSString?let updatedText =লাইনটি রূপান্তর করুন let updatedText = currentText?.replacingCharacters(in: range, with: text)। অবশেষে, if updatedText.isEmptyরেখাকে রূপান্তর করুন if (updatedText?.isEmpty)! {। কৌতুক করা উচিত!
বেলর মিচেল 22

1
@ টিট্রোহোদা আমি অনুলিপিগুলি হ্যান্ডেল করার জন্য পরিস্থিতিতে সমাধানটি আপডেট করেছি
লেন্ডসে স্কট

3
@ লিন্ডসেস্কট এর textView.selectedTextRangeভিতরে থেকে সেটিং func textViewDidChangeSelection(_ textView: UITextView)একটি অসীম লুপের কারণ ...
মাইকেজি

229

ভাসমান স্থানধারক


পাঠ্য দৃশ্যের উপরে কোনও স্থানধারক লেবেল স্থাপন, এটির ফন্ট, রঙ নির্ধারণ এবং পাঠ্য দর্শনের অক্ষর গণনায় পরিবর্তনগুলি ট্র্যাক করে প্লেসোল্ডার দৃশ্যমানতা পরিচালনা করা সহজ, নিরাপদ এবং নির্ভরযোগ্য।

সুইফট 3:

class NotesViewController : UIViewController, UITextViewDelegate {

    @IBOutlet var textView : UITextView!
    var placeholderLabel : UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        textView.delegate = self
        placeholderLabel = UILabel()
        placeholderLabel.text = "Enter some text..."
        placeholderLabel.font = UIFont.italicSystemFont(ofSize: (textView.font?.pointSize)!)
        placeholderLabel.sizeToFit()
        textView.addSubview(placeholderLabel)
        placeholderLabel.frame.origin = CGPoint(x: 5, y: (textView.font?.pointSize)! / 2)
        placeholderLabel.textColor = UIColor.lightGray
        placeholderLabel.isHidden = !textView.text.isEmpty
    }

    func textViewDidChange(_ textView: UITextView) {
        placeholderLabel.isHidden = !textView.text.isEmpty
    }
}

সুইফট 2: একই, ব্যতীত italicSystemFontOfSize(textView.font.pointSize),,UIColor.lightGrayColor



19
এই পদ্ধতিটি অনস্বীকার্যভাবে আমি খুঁজে পেয়েছি সবচেয়ে সহজ এবং সর্বনিম্ন ত্রুটি-প্রবণ। অবিশাস্য।
ডেভিড

6
এটি একটি ভাল পদ্ধতি তবে স্থানধারক পাঠ্য খুব দীর্ঘ হলে লেবেল পাঠ্য সীমার বাইরে চলে যেতে পারে ..
আকস

5
ব্যবহার করা সহজ এবং বিদ্যমান আচরণের সাথে দুর্দান্তভাবে সংহত করে। প্লেসোল্ডার বার্তাটি যেভাবেই হোক ভার্বোস হওয়া উচিত নয় তবে 0-তে লাইনগুলি সেট করে না কী এই সমস্যাটির যত্ন নেবে?
টমমি সি

2
আমি সাধারণত এই পদ্ধতিটি পছন্দ করি, যদিও এটি সমস্যাযুক্ত হলেও যদি পাঠ্যটি কেন্দ্র বিন্যস্ত হয় তবে কার্সারটি তার বাম পরিবর্তে স্থানধারকের শীর্ষে কেন্দ্রীভূত হবে।
ব্লিন্ডার্স

1
@ ব্লুইটার্স - এটি কি সত্যিই অস্বাভাবিক কোণার কেস হবে না? তবে ধরে নিচ্ছি যে এটি একটি মাল্টি-লাইন ইনপুট ক্ষেত্র (সেক্ষেত্রে আমি ধরে নিতেই পারি), আপনি কি স্থানধারক পাঠ্যটিকে কিছুটা দূরে সরানোর জন্য উল্লম্ব অফসেট গণনা সামঞ্জস্য করতে পারবেন না?
স্পষ্টলাইট

35

দৃMP়ভাবে কেএমপিলেসোল্ডার টেক্সটভিউ লাইব্রেরি ব্যবহার করার পরামর্শ দিন । ব্যবহার করা খুব সহজ।


1
এটি এখন পর্যন্ত সবচেয়ে সহজ সমাধান (ইউআইএলবেল যুক্ত করা বা বিশেষ প্রতিনিধিদের জিনিসপত্র জড়িত না)। বাক্সের বাইরে কাজ করে।
হিক্সফিল্ড

এটি কাজ করা উচিত. লেখক বলেছেন যে এটি সুইফট 3.0+
t4nhpt

27

সুইফট:

আপনার পাঠ্য দর্শনটি প্রোগ্রামগতভাবে বা ইন্টারফেস বিল্ডারের মাধ্যমে যুক্ত করুন, যদি শেষ হয় তবে আউটলেটটি তৈরি করুন:

@IBOutlet weak var yourTextView: UITextView!

দয়া করে প্রতিনিধি যুক্ত করুন (UITextViewDelegate):

class ViewController: UIViewController, UITextViewDelegate {

ভিউডিডলড পদ্ধতিতে, নিম্নলিখিতগুলি যুক্ত করুন:

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    yourTextView.delegate = self
    yourTextView.text = "Placeholder text goes right here..."
    yourTextView.textColor = UIColor.lightGray

এখন আমাকে যাদু অংশটি পরিচয় করিয়ে দিন, এই ফাংশনটি যুক্ত করুন:

func textViewDidBeginEditing(_ textView: UITextView) {

    if yourTextView.textColor == UIColor.lightGray {
        yourTextView.text = ""
        yourTextView.textColor = UIColor.black
    }
}

মনে রাখবেন যে যখনই সম্পাদনা শুরু হয় এটি কার্যকর করা হবে, সেখানে আমরা রঙের সম্পত্তি ব্যবহার করে রাষ্ট্রকে জানাতে শর্তগুলি পরীক্ষা করব। পাঠ্য সেট করা হচ্ছেnilআমি পরামর্শ দিই না। তার ঠিক পরে, আমরা পাঠ্য রঙকে কাঙ্ক্ষিততে সেট করেছিলাম, এই ক্ষেত্রে, কালো।

এখন এই ফাংশনটি যুক্ত করুন:

func textViewDidEndEditing(_ textView: UITextView) {

    if yourTextView.text == "" {

        yourTextView.text = "Placeholder text ..."
        yourTextView.textColor = UIColor.lightGray
    }
}

আমাকে জোর দেওয়া যাক, তুলনা করবেন না nil, আমি ইতিমধ্যে এটি চেষ্টা করেছি এবং এটি কার্যকর হবে না। তারপরে আমরা মানগুলি আবার স্থানধারক শৈলীতে সেট করি এবং রঙটিকে আবার স্থানধারক রঙে সেট করে থাকি কারণ এটি চেক ইন করার শর্ত textViewDidBeginEditing


16

এই এক্সটেনশনটি ব্যবহার করুন ইউআইটিেক্সটভিউতে স্থানধারক সেট করার সেরা উপায়। তবে নিশ্চিত হয়ে নিন যে আপনি টেক্সটভিউতে প্রতিনিধিদের সংযুক্ত করেছেন। আপনি স্থানধারককে এভাবে সেট করতে পারেন: -

yourTextView.placeholder = "Placeholder" 

extension UITextView :UITextViewDelegate
{

    /// Resize the placeholder when the UITextView bounds change
    override open var bounds: CGRect {
        didSet {
            self.resizePlaceholder()
        }
    }

    /// The UITextView placeholder text
    public var placeholder: String? {
        get {
            var placeholderText: String?

            if let placeholderLabel = self.viewWithTag(100) as? UILabel {
                placeholderText = placeholderLabel.text
            }

            return placeholderText
        }
        set {
            if let placeholderLabel = self.viewWithTag(100) as! UILabel? {
                placeholderLabel.text = newValue
                placeholderLabel.sizeToFit()
            } else {
                self.addPlaceholder(newValue!)
            }
        }
    }

    /// When the UITextView did change, show or hide the label based on if the UITextView is empty or not
    ///
    /// - Parameter textView: The UITextView that got updated
    public func textViewDidChange(_ textView: UITextView) {
        if let placeholderLabel = self.viewWithTag(100) as? UILabel {
            placeholderLabel.isHidden = self.text.characters.count > 0
        }
    }

    /// Resize the placeholder UILabel to make sure it's in the same position as the UITextView text
    private func resizePlaceholder() {
        if let placeholderLabel = self.viewWithTag(100) as! UILabel? {
            let labelX = self.textContainer.lineFragmentPadding
            let labelY = self.textContainerInset.top - 2
            let labelWidth = self.frame.width - (labelX * 2)
            let labelHeight = placeholderLabel.frame.height

            placeholderLabel.frame = CGRect(x: labelX, y: labelY, width: labelWidth, height: labelHeight)
        }
    }

    /// Adds a placeholder UILabel to this UITextView
    private func addPlaceholder(_ placeholderText: String) {
        let placeholderLabel = UILabel()

        placeholderLabel.text = placeholderText
        placeholderLabel.sizeToFit()

        placeholderLabel.font = self.font
        placeholderLabel.textColor = UIColor.lightGray
        placeholderLabel.tag = 100

        placeholderLabel.isHidden = self.text.characters.count > 0

        self.addSubview(placeholderLabel)
        self.resizePlaceholder()
        self.delegate = self
    }
}

1
মোহন মত কাজ !! আপনাকে অনেক ধন্যবাদ ! :)
নাহিদ রায়হান

প্রিয় সবাইকে স্বাগতম
সন্দীপ গিল

15

আমি অবাক যে কেউ উল্লেখ করেনি NSTextStorageDelegateUITextViewDelegateএর পদ্ধতিগুলি কেবল ব্যবহারকারী ইন্টারঅ্যাকশন দ্বারা ট্রিগার করা হবে, তবে প্রোগ্রামগতভাবে নয়। উদাহরণস্বরূপ, আপনি যখন কোনও পাঠ্য দৃশ্যের textসম্পত্তি প্রোগ্রামক্রমে সেট করবেন তখন আপনাকে স্থানধারকের দৃশ্যমানতাটি নিজেই সেট করতে হবে, কারণ প্রতিনিধিদের পদ্ধতিগুলি কল করা হবে না।

তবে, NSTextStorageDelegateএর textStorage(_:didProcessEditing:range:changeInLength:)পদ্ধতির সাহায্যে, পাঠ্যটিতে কোনও পরিবর্তন সম্পর্কে আপনাকে অবহিত করা হবে, এমনকি এটি প্রোগ্রামগতভাবে করা গেলেও। কেবল এটির মতো নির্ধারণ করুন:

textView.textStorage.delegate = self

(ইন UITextView, এই প্রতিনিধি সম্পত্তি nilডিফল্টরূপে হয়, সুতরাং এটি কোনও ডিফল্ট আচরণকে প্রভাবিত করবে না))

সঙ্গে এটি একত্রিত UILabelকৌশল প্রমান @clearlight, এক সহজে পুরো মোড়ানো পারেন UITextViewএর placeholderএকটি এক্সটেনশন মধ্যে বাস্তবায়ন।

extension UITextView {

    private class PlaceholderLabel: UILabel { }

    private var placeholderLabel: PlaceholderLabel {
        if let label = subviews.compactMap( { $0 as? PlaceholderLabel }).first {
            return label
        } else {
            let label = PlaceholderLabel(frame: .zero)
            label.font = font
            addSubview(label)
            return label
        }
    }

    @IBInspectable
    var placeholder: String {
        get {
            return subviews.compactMap( { $0 as? PlaceholderLabel }).first?.text ?? ""
        }
        set {
            let placeholderLabel = self.placeholderLabel
            placeholderLabel.text = newValue
            placeholderLabel.numberOfLines = 0
            let width = frame.width - textContainer.lineFragmentPadding * 2
            let size = placeholderLabel.sizeThatFits(CGSize(width: width, height: .greatestFiniteMagnitude))
            placeholderLabel.frame.size.height = size.height
            placeholderLabel.frame.size.width = width
            placeholderLabel.frame.origin = CGPoint(x: textContainer.lineFragmentPadding, y: textContainerInset.top)

            textStorage.delegate = self
        }
    }

}

extension UITextView: NSTextStorageDelegate {

    public func textStorage(_ textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int) {
        if editedMask.contains(.editedCharacters) {
            placeholderLabel.isHidden = !text.isEmpty
        }
    }

}

নোট করুন যে কল করা একটি বেসরকারী (নেস্টেড) শ্রেণীর ব্যবহার PlaceholderLabel। এটির কোনও বাস্তবায়ন নেই, তবে এটি আমাদের স্থানধারক লেবেল সনাক্ত করার একটি উপায় সরবরাহ করে যা tagসম্পত্তিটি ব্যবহার করার চেয়ে 'সুইফ্টি' is

এই পদ্ধতির সাথে, আপনি এখনও UITextViewঅন্য কাউকে ডেলিগেট নির্ধারণ করতে পারেন ।

এমনকি আপনার পাঠ্য দর্শনের ক্লাসও পরিবর্তন করতে হবে না। কেবল এক্সটেনশন (গুলি) যুক্ত করুন এবং আপনি UITextViewআপনার প্রকল্পের প্রত্যেককে এমনকি এমনকি ইন্টারফেস বিল্ডারে একটি স্থানধারক স্ট্রিং বরাদ্দ করতে সক্ষম হবেন ।

আমি placeholderColorস্পষ্টতার কারণে কোনও সম্পত্তি প্রয়োগের বিষয়টি বাদ দিয়েছি তবে এটির জন্য একই রকম গণিত ভেরিয়েবলের সাথে আরও কয়েকটি লাইন প্রয়োগ করা যেতে পারে placeholder


খুব মার্জিত সমাধান। আমি এটা ভালোবাসি.
ডেভ ব্যাটন

textView.textStorage.delegate = selfএটি একটি ভিউ-কন্ট্রোলারে আমাদের সেই ভিউ-কন্ট্রোলারের সাথে আবদ্ধ হওয়া প্রয়োজন NSTextStorageDelegate। এটা কি সত্যিই প্রয়োজন?
হেমাং

সহজ এবং একটি কবজ মত কাজ করে। এটি অবশ্যই উত্তর গ্রহণ করতে হবে
কায়সার আব্বাস

@ হেমং এটি পাঠ্য দর্শন নিজেই হচ্ছে NSTextStorageDelegate, ভিউ নিয়ন্ত্রণকারী নয়।
Yesleon

14

আমি দুটি ভিন্ন পাঠ্য দর্শন ব্যবহার করে এটি করেছি:

  1. প্লেগ্রহোল্ডার হিসাবে ব্যবহৃত পটভূমির একটি।
  2. অগ্রভাগের একটি (স্বচ্ছ পটভূমিতে) ব্যবহারকারী প্রকৃতপক্ষে টাইপ করে।

ধারণাটি হ'ল ব্যবহারকারী একবার অগ্রভাগের দৃশ্যে স্টাফ টাইপ করা শুরু করার পরে, পটভূমিতে স্থানধারক অদৃশ্য হয়ে যায় (এবং ব্যবহারকারী সমস্ত কিছু মুছে ফেললে পুনরায় উপস্থিত হবে) সুতরাং এটি একক লাইন পাঠ্য ক্ষেত্রের জন্য ঠিক স্থানধারকের মতো আচরণ করে।

আমি এর জন্য ব্যবহৃত কোডটি এখানে। নোট করুন যে বর্ণনাফিল্ডটি সেই ক্ষেত্র যা ব্যবহারকারীদের টাইপ করে এবং বিবরণপ্লেসোল্ডারটি পটভূমির মধ্যে একটি।

func textViewDidChange(descriptionField: UITextView) {
    if descriptionField.text.isEmpty == false {
        descriptionPlaceholder.text = ""
    } else {
        descriptionPlaceholder.text = descriptionPlaceholderText
    }
}

1
এই উপায়টি কিছুটা হ্যাকি তবে এটি সবচেয়ে সহজ এবং খুব সহজ এবং আপনার পছন্দসই ফলাফল উত্পন্ন করে। ভাল ধারণা
উইলিয়াম টি।

9

ইতিমধ্যে এখানে দুর্দান্ত কিছু পরামর্শের ভিত্তিতে আমি নিম্নলিখিত হালকা ওজনের, ইন্টারফেস-বিল্ডার-সামঞ্জস্যপূর্ণ সাবক্লাস একসাথে রাখতে সক্ষম হয়েছি UITextView, যার:

  • এর মতো স্টাইলযুক্ত কনফিগারযোগ্য স্থানধারক পাঠ্য অন্তর্ভুক্ত UITextField
  • কোনও অতিরিক্ত সাবভিউ বা সীমাবদ্ধতার প্রয়োজন নেই।
  • ভিউকন্ট্রোলারের কাছ থেকে কোনও প্রতিনিধি বা অন্য আচরণের প্রয়োজন হয় না।
  • কোন বিজ্ঞপ্তি প্রয়োজন হয় না।
  • ক্ষেত্রের textসম্পত্তির দিকে তাকানো কোনও পাঠ্য বাইরের শ্রেণি থেকে সম্পূর্ণ পৃথক করে রাখে ।

কোনও উন্নয়নের পরামর্শ স্বাগত, বিশেষত যদি আইওএসের স্থানধারীর রঙটিকে হার্ড-কোডিংয়ের পরিবর্তে কর্মসূচির ভিত্তিতে টানানোর কোনও উপায় থাকে।

সুইফ্ট ভি 5:

import UIKit
@IBDesignable class TextViewWithPlaceholder: UITextView {

    override var text: String! { // Ensures that the placeholder text is never returned as the field's text
        get {
            if showingPlaceholder {
                return "" // When showing the placeholder, there's no real text to return
            } else { return super.text }
        }
        set { super.text = newValue }
    }
    @IBInspectable var placeholderText: String = ""
    @IBInspectable var placeholderTextColor: UIColor = UIColor(red: 0.78, green: 0.78, blue: 0.80, alpha: 1.0) // Standard iOS placeholder color (#C7C7CD). See /programming/31057746/whats-the-default-color-for-placeholder-text-in-uitextfield
    private var showingPlaceholder: Bool = true // Keeps track of whether the field is currently showing a placeholder

    override func didMoveToWindow() {
        super.didMoveToWindow()
        if text.isEmpty {
            showPlaceholderText() // Load up the placeholder text when first appearing, but not if coming back to a view where text was already entered
        }
    }

    override func becomeFirstResponder() -> Bool {
        // If the current text is the placeholder, remove it
        if showingPlaceholder {
            text = nil
            textColor = nil // Put the text back to the default, unmodified color
            showingPlaceholder = false
        }
        return super.becomeFirstResponder()
    }

    override func resignFirstResponder() -> Bool {
        // If there's no text, put the placeholder back
        if text.isEmpty {
            showPlaceholderText()
        }
        return super.resignFirstResponder()
    }

    private func showPlaceholderText() {
        showingPlaceholder = true
        textColor = placeholderTextColor
        text = placeholderText
    }
}

6

ভিউ লোডে SET মান

    txtVw!.autocorrectionType = UITextAutocorrectionType.No
    txtVw!.text = "Write your Placeholder"
    txtVw!.textColor = UIColor.lightGrayColor()



func textViewDidBeginEditing(textView: UITextView) {
    if (txtVw?.text == "Write your Placeholder")

    {
        txtVw!.text = nil
        txtVw!.textColor = UIColor.blackColor()
    }
}

func textViewDidEndEditing(textView: UITextView) {
    if txtVw!.text.isEmpty
    {
        txtVw!.text = "Write your Placeholder"
        txtVw!.textColor = UIColor.lightGrayColor()
    }
    textView.resignFirstResponder()
}

6

আমি কোড থেকে সুবিধাজনক করার চেষ্টা clearlight এর উত্তর

extension UITextView{

    func setPlaceholder() {

        let placeholderLabel = UILabel()
        placeholderLabel.text = "Enter some text..."
        placeholderLabel.font = UIFont.italicSystemFont(ofSize: (self.font?.pointSize)!)
        placeholderLabel.sizeToFit()
        placeholderLabel.tag = 222
        placeholderLabel.frame.origin = CGPoint(x: 5, y: (self.font?.pointSize)! / 2)
        placeholderLabel.textColor = UIColor.lightGray
        placeholderLabel.isHidden = !self.text.isEmpty

        self.addSubview(placeholderLabel)
    }

    func checkPlaceholder() {
        let placeholderLabel = self.viewWithTag(222) as! UILabel
        placeholderLabel.isHidden = !self.text.isEmpty
    }

}

ব্যবহার

override func viewDidLoad() {
    textView.delegate = self
    textView.setPlaceholder()
}

func textViewDidChange(_ textView: UITextView) {
    textView.checkPlaceholder()
}

কয়েক ইস্যু। (1) কোনও এক্সটেনশন যা ইউআইভিউ ট্যাগ সম্পত্তি মান ধরে এবং 'ধার করে' নেয়, এমন ঝুঁকি রয়েছে যে কেউ নিজের ভিউ হায়ারার্কিতে একই ট্যাগটি ব্যবহার করতে পারেন, এক্সটেনশনের ব্যবহার সম্পর্কে অজানা, বাগ সনাক্তকরণের জন্য অত্যন্ত জটিল তৈরি করে creating লাইব্রেরি কোড বা এক্সটেনশনের অন্তর্ভুক্ত নয় এমন জিনিস। (২) এটির জন্য এখনও একজন ডেলিগেট ঘোষণা করার জন্য কলারের প্রয়োজন। ভাসমান প্লেসহোল্ডার হ্যাক এড়াতে একটি ক্ষুদ্র পদাঙ্ক হয়েছে, এটি একটি নিরাপদ বাজি তোলে যা সহজ এবং সম্পূর্ণরূপে স্থানীয় নয়।
clearlight

5

আরও একটি সমাধান (সুইফট 3):

import UIKit

protocol PlaceholderTextViewDelegate {
    func placeholderTextViewDidChangeText(_ text:String)
    func placeholderTextViewDidEndEditing(_ text:String)
}

final class PlaceholderTextView: UITextView {

    var notifier:PlaceholderTextViewDelegate?

    var placeholder: String? {
        didSet {
            placeholderLabel?.text = placeholder
        }
    }
    var placeholderColor = UIColor.lightGray
    var placeholderFont = UIFont.appMainFontForSize(14.0) {
        didSet {
            placeholderLabel?.font = placeholderFont
        }
    }

    fileprivate var placeholderLabel: UILabel?

    // MARK: - LifeCycle

    init() {
        super.init(frame: CGRect.zero, textContainer: nil)
        awakeFromNib()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.delegate = self
        NotificationCenter.default.addObserver(self, selector: #selector(PlaceholderTextView.textDidChangeHandler(notification:)), name: .UITextViewTextDidChange, object: nil)

        placeholderLabel = UILabel()
        placeholderLabel?.textColor = placeholderColor
        placeholderLabel?.text = placeholder
        placeholderLabel?.textAlignment = .left
        placeholderLabel?.numberOfLines = 0
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        placeholderLabel?.font = placeholderFont

        var height:CGFloat = placeholderFont.lineHeight
        if let data = placeholderLabel?.text {

            let expectedDefaultWidth:CGFloat = bounds.size.width
            let fontSize:CGFloat = placeholderFont.pointSize

            let textView = UITextView()
            textView.text = data
            textView.font = UIFont.appMainFontForSize(fontSize)
            let sizeForTextView = textView.sizeThatFits(CGSize(width: expectedDefaultWidth,
                                                               height: CGFloat.greatestFiniteMagnitude))
            let expectedTextViewHeight = sizeForTextView.height

            if expectedTextViewHeight > height {
                height = expectedTextViewHeight
            }
        }

        placeholderLabel?.frame = CGRect(x: 5, y: 0, width: bounds.size.width - 16, height: height)

        if text.isEmpty {
            addSubview(placeholderLabel!)
            bringSubview(toFront: placeholderLabel!)
        } else {
            placeholderLabel?.removeFromSuperview()
        }
    }

    func textDidChangeHandler(notification: Notification) {
        layoutSubviews()
    }

}

extension PlaceholderTextView : UITextViewDelegate {
    // MARK: - UITextViewDelegate
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if(text == "\n") {
            textView.resignFirstResponder()
            return false
        }
        return true
    }

    func textViewDidChange(_ textView: UITextView) {
        notifier?.placeholderTextViewDidChangeText(textView.text)
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        notifier?.placeholderTextViewDidEndEditing(textView.text)
    }
}

ফলাফল

এখানে চিত্র বর্ণনা লিখুন


4

একটি সহজ এবং দ্রুত সমাধান যা আমার পক্ষে কাজ করে তা হ'ল:

@IBDesignable
class PlaceHolderTextView: UITextView {

    @IBInspectable var placeholder: String = "" {
         didSet{
             updatePlaceHolder()
        }
    }

    @IBInspectable var placeholderColor: UIColor = UIColor.gray {
        didSet {
            updatePlaceHolder()
        }
    }

    private var originalTextColor = UIColor.darkText
    private var originalText: String = ""

    private func updatePlaceHolder() {

        if self.text == "" || self.text == placeholder  {

            self.text = placeholder
            self.textColor = placeholderColor
            if let color = self.textColor {

                self.originalTextColor = color
            }
            self.originalText = ""
        } else {
            self.textColor = self.originalTextColor
            self.originalText = self.text
        }

    }

    override func becomeFirstResponder() -> Bool {
        let result = super.becomeFirstResponder()
        self.text = self.originalText
        self.textColor = self.originalTextColor
        return result
    }
    override func resignFirstResponder() -> Bool {
        let result = super.resignFirstResponder()
        updatePlaceHolder()

        return result
    }
}

4

এই কাজের জন্য আমি যা ব্যবহার করছি তা এখানে।

@IBDesignable class UIPlaceholderTextView: UITextView {

    var placeholderLabel: UILabel?

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        sharedInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        sharedInit()
    }

    override func prepareForInterfaceBuilder() {
        sharedInit()
    }

    func sharedInit() {
        refreshPlaceholder()
        NotificationCenter.default.addObserver(self, selector: #selector(textChanged), name: UITextView.textDidChangeNotification, object: nil)
    }

    @IBInspectable var placeholder: String? {
        didSet {
            refreshPlaceholder()
        }
    }

    @IBInspectable var placeholderColor: UIColor? = .darkGray {
        didSet {
            refreshPlaceholder()
        }
    }

    @IBInspectable var placeholderFontSize: CGFloat = 14 {
        didSet {
            refreshPlaceholder()
        }
    }

    func refreshPlaceholder() {
        if placeholderLabel == nil {
            placeholderLabel = UILabel()
            let contentView = self.subviews.first ?? self

            contentView.addSubview(placeholderLabel!)
            placeholderLabel?.translatesAutoresizingMaskIntoConstraints = false

            placeholderLabel?.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: textContainerInset.left + 4).isActive = true
            placeholderLabel?.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: textContainerInset.right + 4).isActive = true
            placeholderLabel?.topAnchor.constraint(equalTo: contentView.topAnchor, constant: textContainerInset.top).isActive = true
            placeholderLabel?.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: textContainerInset.bottom)
        }
        placeholderLabel?.text = placeholder
        placeholderLabel?.textColor = placeholderColor
        placeholderLabel?.font = UIFont.systemFont(ofSize: placeholderFontSize)
    }

    @objc func textChanged() {
        if self.placeholder?.isEmpty ?? true {
            return
        }

        UIView.animate(withDuration: 0.25) {
            if self.text.isEmpty {
                self.placeholderLabel?.alpha = 1.0
            } else {
                self.placeholderLabel?.alpha = 0.0
            }
        }
    }

    override var text: String! {
        didSet {
            textChanged()
        }
    }

}

আমি জানি যে এর মতো বেশ কয়েকটি পদ্ধতি রয়েছে তবে এর থেকে প্রাপ্ত সুবিধাগুলি হ'ল:

  • স্থানধারক পাঠ্য, ফন্টের আকার এবং রঙ সেট করতে পারে আইবি
  • "এর সতর্কতা আর দেখায় না স্ক্রোল ভিউতে দ্ব্যর্থপূর্ণ স্ক্রোলযোগ্য সামগ্রী রয়েছে না।
  • স্থানধারক দেখানোর / আড়াল করতে অ্যানিমেশন যুক্ত করুন ।

3

সুইফট ৩.২

extension EditProfileVC:UITextViewDelegate{

    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.textColor == UIColor.lightGray {
            textView.text = nil
            textView.textColor = UIColor.black
       }
    }
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text.isEmpty {
            textView.text = "Placeholder"
            textView.textColor = UIColor.lightGray
        }
    }
}

প্রথমে যখন ব্যবহারকারী পাঠ্য ভিউডিডবেগইনএডিটিং কল সম্পাদনা করবেন এবং তারপরে যদি পাঠ্য ধূসর বর্ণের রঙ ব্যবহারকারীর কিছু না লিখে থাকে তবে তা পরীক্ষা করুন এবং পাঠ্যদর্শন শূন্য হিসাবে সেট করুন এবং ব্যবহারকারীকে টেক্সট করার জন্য রঙকে কালোতে পরিবর্তন করুন।

যখন ব্যবহারকারীর সম্পাদনা পাঠ্য ভিউডিডএন্ডএডিটিংয়ের শেষে কল করা হয় এবং ব্যবহারকারী পাঠ্যদর্শনটিতে কিছু না লিখেন কিনা তা পরীক্ষা করা হয় তবে পাঠ্য "প্লেসহোল্ডার" সহ ধূসর বর্ণ হিসাবে পাঠ্য সেট করা হয়


3

এই সমস্যাটি সমাধানের আমার উপায় এখানে রয়েছে ( সুইফট 4 ):

ধারণাটি ছিল সহজতম সমাধান তৈরি করা যা বিভিন্ন রঙের স্থানধারককে ব্যবহার করতে দেয়, স্থানধারীদের আকারকে আকার দেয়, এর মধ্যে delegateসমস্ত UITextViewফাংশন প্রত্যাশা অনুযায়ী কাজ করে ওভাররাইট করে না ।

import UIKit

class PlaceholderTextView: UITextView {
    var placeholderColor: UIColor = .lightGray
    var defaultTextColor: UIColor = .black

    private var isShowingPlaceholder = false {
        didSet {
            if isShowingPlaceholder {
                text = placeholder
                textColor = placeholderColor
            } else {
                textColor = defaultTextColor
            }
        }
    }

    var placeholder: String? {
        didSet {
            isShowingPlaceholder = !hasText
        }
    }

    @objc private func textViewDidBeginEditing(notification: Notification) {
        textColor = defaultTextColor
        if isShowingPlaceholder { text = nil }
    }

    @objc private func textViewDidEndEditing(notification: Notification) {
        isShowingPlaceholder = !hasText
    }

    // MARK: - Construction -
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    private func setup() {
        NotificationCenter.default.addObserver(self, selector: #selector(textViewDidBeginEditing(notification:)), name: UITextView.textDidBeginEditingNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(textViewDidEndEditing(notification:)), name: UITextView.textDidEndEditingNotification, object: nil)
    }

    // MARK: - Destruction -
    deinit { NotificationCenter.default.removeObserver(self) }
}

এটি একটি দুর্দান্ত এবং সাধারণ সমাধান।
জেরেডএইচ

2

আমি জানি না কেন লোকেরা এই বিষয়টিকে এত জটিল করে তোলে .... এটি মোটামুটি সোজা এগিয়ে এবং সহজ। এখানে ইউআইটিেক্সটভিউয়ের একটি সাবক্লাস রয়েছে যা অনুরোধকৃত কার্যকারিতা সরবরাহ করে।

- (void)customInit
{
    self.contentMode = UIViewContentModeRedraw;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}

    - (void)textChanged:(NSNotification *)notification
    {
        if (notification.object == self) {
            if(self.textStorage.length != 0 || !self.textStorage.length) {
                [self setNeedsDisplay];
            }
        }
    }


    #pragma mark - Setters

    - (void)setPlaceholderText:(NSString *)placeholderText withFont:(UIFont *)font
    {
        self.placeholderText = placeholderText;
        self.placeholderTextFont = font;

    }



    - (void)drawRect:(CGRect)rect
    {
        [super drawRect:rect];
        [[UIColor lightGrayColor] setFill];

        if (self.textStorage.length != 0) {
            return;
        }

        CGRect inset = CGRectInset(rect, 8, 8);//Default rect insets for textView
        NSDictionary *attributes =  @{NSFontAttributeName: self.placeholderTextFont, NSForegroundColorAttributeName: [UIColor grayColor]};
        [self.placeholderText drawInRect:inset withAttributes:attributes];
    }`

এফওয়াইআই, কেউ আমাকে মারধর করার আগে ... এটি সুইফটে অনুবাদ করার পক্ষে মোটামুটি সরাসরি। এখানে জটিল কিছুই না।
TheCodingArt

2

আপনি যদি একাধিক পাঠ্য দর্শন নিয়ে কাজ করছেন তবে এটি সমাধানটি ব্যবহার করতে আমার প্রস্তুত

func textViewShouldBeginEditing(textView: UITextView) -> Bool {        
    // Set cursor to the beginning if placeholder is set
    if textView.textColor == UIColor.lightGrayColor() {
        textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument)
    }

    return true
}

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    // Remove placeholder
    if textView.textColor == UIColor.lightGrayColor() && text.characters.count > 0 {
        textView.text = ""
        textView.textColor = UIColor.blackColor()
    }

    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }

    return true
}

func textViewDidChange(textView: UITextView) {
    // Set placeholder if text is empty
    if textView.text.isEmpty {
        textView.text = NSLocalizedString("Hint", comment: "hint")
        textView.textColor = UIColor.lightGrayColor()
        textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument)
    }
}

func textViewDidChangeSelection(textView: UITextView) {
    // Set cursor to the beginning if placeholder is set
    let firstPosition = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument)

    // Do not change position recursively
    if textView.textColor == UIColor.lightGrayColor() && textView.selectedTextRange != firstPosition {
        textView.selectedTextRange = firstPosition
    }
}

এটা খুব সুন্দর!
কেভিনভিউড

2

সুইফট ৩.১

এই এক্সটেনশনটি আমার পক্ষে ভালভাবে কাজ করেছে: https://github.com/devxoul/UITextView- স্থানধারক

এখানে একটি কোড স্নিপেট:

এটি শুঁটির মাধ্যমে ইনস্টল করুন:

pod 'UITextView+Placeholder', '~> 1.2'

এটি আপনার ক্লাসে আমদানি করুন

import UITextView_Placeholder

এবং placeholderআপনার ইতিমধ্যে তৈরি সম্পত্তি যুক্ত করুনUITextView

textView.placeholder = "Put some detail"

এটি ... এটি দেখতে কেমন দেখাচ্ছে (তৃতীয় বাক্সটি একটি UITextView) এখানে চিত্র বর্ণনা লিখুন


2

পক্ষান্তরে শুধু এই পোস্টে যে উত্তর সম্পর্কে, UITextView না একটি স্থানধারক সম্পত্তি আছে। আমার বোধগম্যতার বাইরে, এটি কেবল আইবিতে প্রকাশিত হয়েছে, যেমন:

<userDefinedRuntimeAttributes>
  <userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="My Placeholder"/>
</userDefinedRuntimeAttributes>

সুতরাং আপনি যদি স্টোরিবোর্ড ব্যবহার করছেন এবং একটি স্থির স্থানধারক পর্যাপ্ত পরিমাণে থাকে তবে কেবল সম্পত্তি পরিদর্শকের উপর সেট করুন।

আপনি এই সম্পত্তিটিকে এই কোডগুলিতেও সেট করতে পারেন:

textView.setValue("My Placeholder", forKeyPath: "placeholder")

আবহাওয়া হিসাবে এর মেঘাচ্ছন্ন সম্পত্তি হিসাবে ব্যক্তিগত বেসরকারী API এর মাধ্যমে এটি অ্যাক্সেস করা হয় উন্মুক্ত হওয়ার সাথে সাথে হয়।

আমি এই পদ্ধতির সাথে জমা দেওয়ার চেষ্টা করিনি। তবে আমি শীঘ্রই এইভাবে জমা দেব এবং সেই অনুসারে এই উত্তরটি আপডেট করব।

হালনাগাদ:

আমি অ্যাপল থেকে কোনও সমস্যা ছাড়াই একাধিক প্রকাশে এই কোডটি প্রেরণ করেছি।

আপডেট: এটি কেবলমাত্র এক্সকোড পূর্ববর্তী 11.2 এ কাজ করবে


সুইফ্ট 5 এ আপনি আমার টেক্সটভিউ লিখতে পারেন, স্থানধারক = "আপনার চোখের রঙ প্রবেশ করান"
ব্যবহারকারী 46292990

@ user462990 আপনি কি এর জন্য একটি ডকুমেন্টেশন লিঙ্ক সরবরাহ করতে পারেন? আমি বিশ্বাস করি না এটি সঠিক।
অ্যালেক্স চিজ

দুঃখিত, ডক্সটি খুঁজে পেলেন না তবে এটি পরীক্ষা করা সত্যই সহজ ... যেমন টেক্সটফিল্ড 3.প্লেসোল্ডার = ল্যাংগুয়েজ.জেবি লোকালাইজ ("আপনার নাম") L। জেবিলোক্যালাইজ অনুবাদ ম্যানেজার যা একটি রিটার্ন দেয় স্ট্রিং
ব্যবহারকারীর 46292990

3
@ user462990 আপনি উল্লেখ করছেন UITextFieldনা UITextView দয়া করে প্রশ্নগুলি / প্রতিক্রিয়াগুলি আরও মনোযোগ সহকারে পড়ুন।
অ্যালেক্স চিজ

3
দুর্দান্ত সমাধান, তবে আমার পক্ষে কাজ করে না। কোনও না কোনওভাবে সর্বদা ক্রাশ হয়। আপনি যে ডিপোরিয়মেন্ট টার্গেট, সুইফট এবং এক্সকোড সংস্করণ ব্যবহার করছেন তা নির্দিষ্ট করতে পারবেন?
টি। প্যাসিইনিক

1

আইটিওতে টেক্সটভিউতে সরাসরি স্থানধারক যুক্ত করার মতো কোনও সম্পত্তি নেই বরং আপনি একটি লেবেল যুক্ত করতে পারেন এবং টেক্সটভিউতে পরিবর্তনটি লুকিয়ে রাখতে / লুকিয়ে রাখতে পারেন। সুইফট ২.০ এবং পাঠ্যদর্শন ডেলেগেটটি বাস্তবায়নের বিষয়টি নিশ্চিত করুন

func textViewDidChange(TextView: UITextView)
{

 if  txtShortDescription.text == ""
    {
        self.lblShortDescription.hidden = false
    }
    else
    {
        self.lblShortDescription.hidden = true
    }

}

1

সুইফ্ট - আমি এমন একটি ক্লাস লিখেছিলাম যা ইউআইটিেক্সটভিউ উত্তরাধিকার সূত্রে পেয়েছে এবং আমি একটি স্থানধারক হিসাবে কাজ করার জন্য একটি ইউআইএলবেলকে একটি সংক্ষিপ্তসার হিসাবে যুক্ত করেছি।

  import UIKit
  @IBDesignable
  class HintedTextView: UITextView {

      @IBInspectable var hintText: String = "hintText" {
          didSet{
              hintLabel.text = hintText
          }
      }

      private lazy var hintLabel: UILabel = {
          let label = UILabel()
          label.font = UIFont.systemFontOfSize(16)
          label.textColor = UIColor.lightGrayColor()
          label.translatesAutoresizingMaskIntoConstraints = false
          return label
      }()


      override init(frame: CGRect, textContainer: NSTextContainer?) {
          super.init(frame: frame, textContainer: textContainer)
          setupView()
      }

      required init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
         setupView()
      }

      override func prepareForInterfaceBuilder() {
         super.prepareForInterfaceBuilder()
         setupView()
      }

      private func setupView() {

        translatesAutoresizingMaskIntoConstraints = false
        delegate = self
        font = UIFont.systemFontOfSize(16)

        addSubview(hintLabel)

        NSLayoutConstraint.activateConstraints([

           hintLabel.leftAnchor.constraintEqualToAnchor(leftAnchor, constant: 4),
           hintLabel.rightAnchor.constraintEqualToAnchor(rightAnchor, constant: 8),
           hintLabel.topAnchor.constraintEqualToAnchor(topAnchor, constant: 4),
           hintLabel.heightAnchor.constraintEqualToConstant(30)
         ])
        }

      override func layoutSubviews() {
        super.layoutSubviews()
        setupView()
     }

}

স্থানধারকের অবস্থান নির্ধারণে সীমাবদ্ধতা ব্যবহারের দুর্দান্ত উদাহরণ, তবে স্থানধারকের আদর্শ অবস্থান ঠিক যেখানে উপরের পাঠ্যের প্রথম অক্ষরটি চলেছে, তাই পাঠ্য দর্শনের ফন্টের ভিত্তিতে সেই অবস্থানটি গণনা করা তার পক্ষে ভাল কারণ এটি মানিয়ে যায় পাঠ্য দর্শনের জন্য হরফের আকারের যা যা সেট করা হয়েছে।
ক্লিয়ারলাইট

1

আমি @ নার্ডিস্টের সমাধানটি পছন্দ করি। তার ভিত্তিতে, আমি এতে একটি এক্সটেনশন তৈরি করেছি UITextView:

import Foundation
import UIKit

extension UITextView
{
  private func add(_ placeholder: UILabel) {
    for view in self.subviews {
        if let lbl = view as? UILabel  {
            if lbl.text == placeholder.text {
                lbl.removeFromSuperview()
            }
        }
    }
    self.addSubview(placeholder)
  }

  func addPlaceholder(_ placeholder: UILabel?) {
    if let ph = placeholder {
      ph.numberOfLines = 0  // support for multiple lines
      ph.font = UIFont.italicSystemFont(ofSize: (self.font?.pointSize)!)
      ph.sizeToFit()
      self.add(ph)
      ph.frame.origin = CGPoint(x: 5, y: (self.font?.pointSize)! / 2)
      ph.textColor = UIColor(white: 0, alpha: 0.3)
      updateVisibility(ph)
    }
  }

  func updateVisibility(_ placeHolder: UILabel?) {
    if let ph = placeHolder {
      ph.isHidden = !self.text.isEmpty
    }
  }
}

একটি ভিউকন্ট্রোলার ক্লাসে, উদাহরণস্বরূপ, আমি এটি এটি ব্যবহার করি:

class MyViewController: UIViewController, UITextViewDelegate {
  private var notePlaceholder: UILabel!
  @IBOutlet weak var txtNote: UITextView!
  ...
  // UIViewController
  override func viewDidLoad() {
    notePlaceholder = UILabel()
    notePlaceholder.text = "title\nsubtitle\nmore..."
    txtNote.addPlaceholder(notePlaceholder)
    ...
  }

  // UITextViewDelegate
  func textViewDidChange(_ textView: UITextView) {
    txtNote.updateVisbility(notePlaceholder)
    ...
  }

ইউআইটিেক্সটভিউতে স্থানধারক!

এখানে চিত্র বর্ণনা লিখুন

আপডেট :

আপনি কোডে পাঠ্যদর্শনটির পাঠ্য পরিবর্তন করার ক্ষেত্রে, স্থানধারককে আড়াল করার জন্য আপডেটটি কল করুন ভিসিবিট পদ্ধতিতে:

txtNote.text = "something in code"
txtNote.updateVisibility(self.notePlaceholder) // hide placeholder if text is not empty.

স্থানধারকটিকে একাধিকবার যুক্ত হওয়া রোধ করতে একটি ব্যক্তিগত add()ফাংশন যুক্ত করা হয়েছে extension


আসলটিতে আপনার উন্নতির জন্য আবারও ধন্যবাদ। আমি এই সপ্তাহান্তে wayyy খুব বেশী সময় অতিবাহিত, কিন্তু আমি মনে করি আপনি ইজেড প্লেসহোল্ডার চরম বৈকল্পিক আমি অবশেষে নিয়ে এসেছেন উপভোগ করবেন: stackoverflow.com/a/41081244/2079103 (আমি আপনি বিবর্তন অবদান করার জন্য ক্রেডিট দিয়েছি স্থানধারক সমাধান)
1716 এ স্পষ্টলাইট

1

সুইফট ২.২ এ:

public class CustomTextView: UITextView {

private struct Constants {
    static let defaultiOSPlaceholderColor = UIColor(red: 0.0, green: 0.0, blue: 0.0980392, alpha: 0.22)
}
private let placeholderLabel: UILabel = UILabel()

private var placeholderLabelConstraints = [NSLayoutConstraint]()

@IBInspectable public var placeholder: String = "" {
    didSet {
        placeholderLabel.text = placeholder
    }
}

@IBInspectable public var placeholderColor: UIColor = CustomTextView.Constants.defaultiOSPlaceholderColor {
    didSet {
        placeholderLabel.textColor = placeholderColor
    }
}

override public var font: UIFont! {
    didSet {
        placeholderLabel.font = font
    }
}

override public var textAlignment: NSTextAlignment {
    didSet {
        placeholderLabel.textAlignment = textAlignment
    }
}

override public var text: String! {
    didSet {
        textDidChange()
    }
}

override public var attributedText: NSAttributedString! {
    didSet {
        textDidChange()
    }
}

override public var textContainerInset: UIEdgeInsets {
    didSet {
        updateConstraintsForPlaceholderLabel()
    }
}

override public init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    commonInit()
}

required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonInit()
}

private func commonInit() {
    NSNotificationCenter.defaultCenter().addObserver(self,
                                                     selector: #selector(textDidChange),
                                                     name: UITextViewTextDidChangeNotification,
                                                     object: nil)

    placeholderLabel.font = font
    placeholderLabel.textColor = placeholderColor
    placeholderLabel.textAlignment = textAlignment
    placeholderLabel.text = placeholder
    placeholderLabel.numberOfLines = 0
    placeholderLabel.backgroundColor = UIColor.clearColor()
    placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
    addSubview(placeholderLabel)
    updateConstraintsForPlaceholderLabel()
}

private func updateConstraintsForPlaceholderLabel() {
    var newConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(\(textContainerInset.left + textContainer.lineFragmentPadding))-[placeholder]",
                                                                        options: [],
                                                                        metrics: nil,
                                                                        views: ["placeholder": placeholderLabel])
    newConstraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-(\(textContainerInset.top))-[placeholder]",
                                                                     options: [],
                                                                     metrics: nil,
                                                                     views: ["placeholder": placeholderLabel])
    newConstraints.append(NSLayoutConstraint(
        item: placeholderLabel,
        attribute: .Width,
        relatedBy: .Equal,
        toItem: self,
        attribute: .Width,
        multiplier: 1.0,
        constant: -(textContainerInset.left + textContainerInset.right + textContainer.lineFragmentPadding * 2.0)
        ))
    removeConstraints(placeholderLabelConstraints)
    addConstraints(newConstraints)
    placeholderLabelConstraints = newConstraints
}

@objc private func textDidChange() {
    placeholderLabel.hidden = !text.isEmpty
}

public override func layoutSubviews() {
    super.layoutSubviews()
    placeholderLabel.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2.0
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self,
                                                        name: UITextViewTextDidChangeNotification,
                                                        object: nil)
}

}

সুইফট ইন:

import UIKit

শ্রেণি কাস্টম টেক্সটভিউ: ইউআইটিেক্সটভিউ {

private struct Constants {
    static let defaultiOSPlaceholderColor = UIColor(red: 0.0, green: 0.0, blue: 0.0980392, alpha: 0.22)
}
private let placeholderLabel: UILabel = UILabel()

private var placeholderLabelConstraints = [NSLayoutConstraint]()

@IBInspectable public var placeholder: String = "" {
    didSet {
        placeholderLabel.text = placeholder
    }
}

@IBInspectable public var placeholderColor: UIColor = CustomTextView.Constants.defaultiOSPlaceholderColor {
    didSet {
        placeholderLabel.textColor = placeholderColor
    }
}

override public var font: UIFont! {
    didSet {
        placeholderLabel.font = font
    }
}

override public var textAlignment: NSTextAlignment {
    didSet {
        placeholderLabel.textAlignment = textAlignment
    }
}

override public var text: String! {
    didSet {
        textDidChange()
    }
}

override public var attributedText: NSAttributedString! {
    didSet {
        textDidChange()
    }
}

override public var textContainerInset: UIEdgeInsets {
    didSet {
        updateConstraintsForPlaceholderLabel()
    }
}

override public init(frame: CGRect, textContainer: NSTextContainer?) {
    super.init(frame: frame, textContainer: textContainer)
    commonInit()
}

required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonInit()
}

private func commonInit() {
    NotificationCenter.default.addObserver(self,
                                                     selector: #selector(textDidChange),
                                                     name: NSNotification.Name.UITextViewTextDidChange,
                                                     object: nil)

    placeholderLabel.font = font
    placeholderLabel.textColor = placeholderColor
    placeholderLabel.textAlignment = textAlignment
    placeholderLabel.text = placeholder
    placeholderLabel.numberOfLines = 0
    placeholderLabel.backgroundColor = UIColor.clear
    placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
    addSubview(placeholderLabel)
    updateConstraintsForPlaceholderLabel()
}

private func updateConstraintsForPlaceholderLabel() {
    var newConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(\(textContainerInset.left + textContainer.lineFragmentPadding))-[placeholder]",
        options: [],
        metrics: nil,
        views: ["placeholder": placeholderLabel])
    newConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(\(textContainerInset.top))-[placeholder]",
        options: [],
        metrics: nil,
        views: ["placeholder": placeholderLabel])
    newConstraints.append(NSLayoutConstraint(
        item: placeholderLabel,
        attribute: .width,
        relatedBy: .equal,
        toItem: self,
        attribute: .width,
        multiplier: 1.0,
        constant: -(textContainerInset.left + textContainerInset.right + textContainer.lineFragmentPadding * 2.0)
    ))
    removeConstraints(placeholderLabelConstraints)
    addConstraints(newConstraints)
    placeholderLabelConstraints = newConstraints
}

@objc private func textDidChange() {
    placeholderLabel.isHidden = !text.isEmpty
}

public override func layoutSubviews() {
    super.layoutSubviews()
    placeholderLabel.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2.0
}

deinit {
    NotificationCenter.default.removeObserver(self,
                                                        name: NSNotification.Name.UITextViewTextDidChange,
                                                        object: nil)
}

}

আমি দ্রুত একটি ক্লাস লিখেছি। আপনার যখনই প্রয়োজন হবে তখন এই ক্লাসটি আমদানি করতে হবে।


দয়া করে এটি সুইফটের কোন সংস্করণটির জন্য উল্লেখ করুন (সুইফট 3 এর জন্য কাজ করে না)
30:48

1

খ্যাতির কারণে আমি মন্তব্য যুক্ত করতে পারি না। ক্লিয়ারলাইট উত্তরে আরও একটি প্রতিনিধি প্রয়োজন যুক্ত করুন।

func textViewDidBeginEditing(_ textView: UITextView) { 
        cell.placeholderLabel.isHidden = !textView.text.isEmpty
}

প্রয়োজন হয়

কারণ textViewDidChangeপ্রথমবার বলা হয় না


1

না পাঠ্য দর্শনের জন্য কোনও স্থানধারক উপলব্ধ নেই। ব্যবহারকারী যখন পাঠ্যদর্শনটিতে প্রবেশ করেন তখন আপনাকে এটির উপরে লেবেল স্থাপন করতে হবে যখন ব্যবহারকারী প্রবেশ করে সমস্ত মান মুছে ফেলেন তখন এটি লুকান বা ডিফল্ট মান অনুসারে সেট করুন।


1

func setPlaceholder(){
var placeholderLabel = UILabel()
        placeholderLabel.text = "Describe your need..."
        placeholderLabel.font = UIFont.init(name: "Lato-Regular", size: 15.0) ?? UIFont.boldSystemFont(ofSize: 14.0)
        placeholderLabel.sizeToFit()
        descriptionTextView.addSubview(placeholderLabel)
        placeholderLabel.frame.origin = CGPoint(x: 5, y: (descriptionTextView.font?.pointSize)! / 2)
        placeholderLabel.textColor = UIColor.lightGray
        placeholderLabel.isHidden = !descriptionTextView.text.isEmpty
}



//Delegate Method.

func textViewDidChange(_ textView: UITextView) {
        placeholderLabel.isHidden = !textView.text.isEmpty
    }
	


1

সম্পাদনা শেষ হয়ে গেলে আমার স্থানধারক পাঠ্যটি আবার উপস্থিত হতে আমাকে কাতারে পাঠাতে হয়েছিল।

func textViewDidBeginEditing(_ textView: UITextView) {

    if textView.text == "Description" {
        textView.text = nil
    }
}

func textViewDidEndEditing(_ textView: UITextView) {

    if textView.text.isEmpty {
        DispatchQueue.main.async {
            textView.text = "Description"
        }
    }
}

আমি শেষ লাইনের "টেক্সটভিউ.টেক্সট =" বিবরণ "এর পরিবর্তে কী লিখব যদি আমি এই মানটি ব্যবহারকারী কী টাইপ করছেন তা হতে চাই?
আইএসএস

1

সুইফট:

আপনার যুক্ত করুন TextView @IBOutlet:

@IBOutlet weak var txtViewMessage: UITextView!

ইন viewWillAppearপদ্ধতি, যোগ নিচের কাজগুলো করুন:

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

    txtViewMessage.delegate = self    // Give TextViewMessage delegate Method

    txtViewMessage.text = "Place Holder Name"
    txtViewMessage.textColor = UIColor.lightGray

}

দয়া করে Delegateব্যবহার এক্সটেনশন যুক্ত করুন (UITextViewDelegate):

// MARK: - UITextViewDelegate
extension ViewController: UITextViewDelegate
{

    func textViewDidBeginEditing(_ textView: UITextView)
    {

        if !txtViewMessage.text!.isEmpty && txtViewMessage.text! == "Place Holder Name"
        {
            txtViewMessage.text = ""
            txtViewMessage.textColor = UIColor.black
        }
    }

    func textViewDidEndEditing(_ textView: UITextView)
    {

        if txtViewMessage.text.isEmpty
        {
            txtViewMessage.text = "Place Holder Name"
            txtViewMessage.textColor = UIColor.lightGray
        }
    }
}

1

আমাদের সমাধান সেই বৈশিষ্ট্য UITextView textএবং textColorবৈশিষ্ট্যগুলির সাথে কৌতুক এড়ানো এড়ায় যা আপনি একটি চরিত্রের কাউন্টার বজায় রাখলে কার্যকর hand

ইহা সাধারণ:

1) UITextViewমাস্টার হিসাবে একই বৈশিষ্ট্য সহ স্টোরিবোর্ডে একটি ডামি তৈরি করুন UITextView। ডামি পাঠ্যে স্থানধারক পাঠ্য বরাদ্দ করুন।

2) দুটির উপরের, বাম এবং ডান প্রান্তটি সারিবদ্ধ করুন UITextViews.

3) মাস্টির পিছনে ডামি রাখুন।

৪) textViewDidChange(textView:)মাস্টারের ডেলিগেট ফাংশনটি ওভাররাইড করুন এবং মাস্টারের 0 টি অক্ষর থাকলে ডামি প্রদর্শন করুন। অন্যথায়, মাস্টার দেখান।

এটি ধরে নেয় উভয়েরই UITextViewsস্বচ্ছ ব্যাকগ্রাউন্ড রয়েছে। যদি তা না করে তবে 0 টি অক্ষর থাকা অবস্থায় ডামিটিকে শীর্ষে রাখুন এবং> 0 টি অক্ষর থাকলে নীচে এটি চাপুন। কার্সারটি সঠিকভাবে অনুসরণ করেছে তা নিশ্চিত করতে আপনাকে প্রতিক্রিয়াকারীদেরও অদলবদল করতে হবে UITextView


1

সুইফট 4, 4.2 এবং 5

[![@IBOutlet var detailTextView: UITextView!

override func viewDidLoad() {
        super.viewDidLoad()
        detailTextView.delegate = self
}

extension ContactUsViewController : UITextViewDelegate {

    public func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.text == "Write your message here..." {
            detailTextView.text = ""
            detailTextView.textColor = UIColor.init(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.86)

        }
        textView.becomeFirstResponder()
    }

    public func textViewDidEndEditing(_ textView: UITextView) {

        if textView.text == "" {
            detailTextView.text = "Write your message here..."
            detailTextView.textColor = UIColor.init(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.30)
        }
        textView.resignFirstResponder()
    }
[![}][1]][1]

এটা কাজ করেছে ! ধন্যবাদ
রক্ষিতা মুরঙ্গা রডরিগো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.