স্ট্রিং ইন সুইফটের ভিত্তিতে ইউআইএলবেলের আকার বের করুন


182

আমি বিভিন্ন স্ট্রিং দৈর্ঘ্যের উপর ভিত্তি করে কোনও ইউআইএলবেলের উচ্চতা গণনা করার চেষ্টা করছি।

func calculateContentHeight() -> CGFloat{
    var maxLabelSize: CGSize = CGSizeMake(frame.size.width - 48, CGFloat(9999))
    var contentNSString = contentText as NSString
    var expectedLabelSize = contentNSString.boundingRectWithSize(maxLabelSize, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(16.0)], context: nil)
    print("\(expectedLabelSize)")
    return expectedLabelSize.size.height

}

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


ডুপ্লিকেট এই চেষ্টা stackoverflow.com/a/61887135/6314955
Malith Kuruwita

উত্তর:


517

চালু একটি এক্সটেনশন ব্যবহার করুন String

সুইফট 3

extension String {
    func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.height)
    }

    func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.width)
    }
}

এবং এছাড়াও NSAttributedString(যা সময়ে সময়ে খুব দরকারী)

extension NSAttributedString {
    func height(withConstrainedWidth width: CGFloat) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)

        return ceil(boundingBox.height)
    }

    func width(withConstrainedHeight height: CGFloat) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)

        return ceil(boundingBox.width)
    }
}

সুইফট 4

শুধু মান পরিবর্তন attributesমধ্যে extension Stringপদ্ধতি

থেকে

[NSFontAttributeName: font]

প্রতি

[.font : font]

2
@ কোডি ওয়েভার প্রস্থের উইথকন্ট্রাইনডহাইট পদ্ধতির জন্য সম্পাদনাটি পরীক্ষা করুন।
কান দেদেগলু

7
@ কানডেদেগলু এইভাবে কীভাবে ডায়নামিক উচ্চতার স্ট্রিংয়ের সাথে কাজ করবেন যখন আপনি "নাম্বারফলাইন" = 0 ব্যবহার করেন (যা ইউআইলাবেল নির্দিষ্ট হতে পারে, নিশ্চিত নয়) বা লাইনব্র্যাকমোড বাইওয়ার্ড র্যাপিং। আমার ধারণা এটির মতো বৈশিষ্ট্যে এটি যুক্ত করা হয়েছিল [NSFontAttributeName: font, NSLineBreakMode: .ByWordWrapping]তবে এটি কার্যকর হয়নি
ফ্রান্সিস্ক0

1
ভাবুন আমি আমার উত্তরটি বের করেছিলাম। আমার NSParagraphStyleAttributeName : styleযেখানে স্টাইলটি এনএস পরিবর্তনযোগ্য প্যারাগ্রাফ স্টাইল
ফ্রান্সিস্ক0

4
আমাকে 'বাউন্ডিংআরেক্ট'-এর পরিবর্তে' সেল্ফ.বাউন্ডিংআরেক্ট 'লিখতে হবে অন্যথায় আমি একটি সংকলন ত্রুটি পেয়েছি।
মাইক এম

1
এই উত্তরটি আমি যখন এটি ব্যবহার পেয়েছি সঙ্গে একটা জিনিষ sizeForItemAtIndexPathএকটি UICollectionViewএটি বিনিময়ে ওভাররাইড করতে মনে হয়insetForSectionAt
জ্যাক শাপিরো

15

মাল্টলাইন পাঠ্যের জন্য এই উত্তরটি সঠিকভাবে কাজ করছে না। ইউআইএলবেল ব্যবহার করে আপনি একটি আলাদা স্ট্রিং এক্সটেনশন তৈরি করতে পারেন

extension String {
func height(constraintedWidth width: CGFloat, font: UIFont) -> CGFloat {
    let label =  UILabel(frame: CGRect(x: 0, y: 0, width: width, height: .greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.text = self
    label.font = font
    label.sizeToFit()

    return label.frame.height
 }
}

UILabel একটি নির্দিষ্ট প্রস্থ পেয়েছে এবং .NumberOfLines 0 এ সেট করা হয়েছে। পাঠ্য যোগ করে এবং .sizeToFit () কল করে এটি স্বয়ংক্রিয়ভাবে সঠিক উচ্চতার সাথে সামঞ্জস্য হয়।

কোডটি সুইফট 3 written এ লেখা হয় 🔶🐦


15
সাইজ টোফিট অঙ্কনের অনেকগুলি পাসের কারণে মিলিয়ন পারফোমেন্স ইস্যু প্রবর্তন করে। আকারে ম্যানুয়ালি গণনা করা সম্পদের দিক থেকে সস্তা
মার্কো পাপালার্ডো

2
সঠিক উচ্চতা নিশ্চিত করতে এই সমাধানটি ইউআইএলবেলের ইউআইএফএন্ট সেট করা উচিত।
ম্যাথু স্পেন্সার

আমার পক্ষে নিখুঁতভাবে কাজ করে - খালি স্ট্রিংয়ের জন্যও অ্যাকাউন্ট (স্বীকৃত উত্তরের মতো নয়)। স্বয়ংক্রিয় উচ্চতার ঘরগুলির সাথে কোনও টেবিলভিউয়ের উচ্চতা গণনা করার জন্য খুব সহজ!
হেন্ডিজ 17

আমি দেখেছি যে গৃহীত উত্তরটি একটি নির্দিষ্ট প্রস্থের জন্য কাজ করেছে তবে নির্দিষ্ট উচ্চতার জন্য নয় not একটি নির্দিষ্ট উচ্চতার জন্য, পাঠ্যটিতে একটি লাইন বিরতি না থাকলে এটি কেবল এক লাইনের সমস্ত কিছুর জন্য প্রস্থকে বাড়িয়ে তুলবে। এখানে আমার বিকল্প উত্তর: আমার উত্তর
এমএসিমিক

2
আমি অনুরূপ সমাধান পোস্ট করেছিsizeToFit
রায়ানজি

6

তিনি আমার পক্ষে কাজ করার সহজ সমাধান ... পোস্ট করা অন্যদের মতো, তবে এটি কল করার প্রয়োজনীয়তা অন্তর্ভুক্ত করে না sizeToFit

নোট করুন এটি সুইফট 5 এ লেখা হয়েছে

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.font = UIFont.systemFont(ofSize: 12) // make sure you set this correctly 
lbl.text = "My text that may or may not wrap lines..."

let width = 100.0 // the width of the view you are constraint to, keep in mind any applied margins here

let height = lbl.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height

এই লাইন মোড়ানো এবং অন্যান্য পরিচালনা করে। সর্বাধিক মার্জিত কোড নয়, তবে এটি কাজটি করে।


2
extension String{

    func widthWithConstrainedHeight(_ height: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: height)

        let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.width)
    }

    func heightWithConstrainedWidth(_ width: CGFloat, font: UIFont) -> CGFloat? {
        let constraintRect = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return ceil(boundingBox.height)
    }

}

1

এটি সুইফট ৪.১ এবং এক্সকোড ৯.৪.১ এ আমার উত্তর

//This is your label
let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height))
proNameLbl.text = "This is your text"
proNameLbl.font = UIFont.systemFont(ofSize: 17)
proNameLbl.numberOfLines = 0
proNameLbl.lineBreakMode = .byWordWrapping
infoView.addSubview(proNameLbl)

//Function to calculate height for label based on text
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat {
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

এখন আপনি এই ফাংশন কল

//Call this function
let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
print(height)//Output : 41.0

1

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

প্রস্থের ফাংশন উচ্চতা ফাংশনটিকে একাধিকবার কল করে তবে এটি একটি দ্রুত গণনা এবং আমি কোনও ইউআইটিবেলের সারিগুলিতে ফাংশনটি ব্যবহার করে পারফরম্যান্সের সমস্যাগুলি লক্ষ্য করি না।

extension String {

    public func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font : font], context: nil)

        return ceil(boundingBox.height)
    }

    public func width(withConstrainedHeight height: CGFloat, font: UIFont, minimumTextWrapWidth:CGFloat) -> CGFloat {

        var textWidth:CGFloat = minimumTextWrapWidth
        let incrementWidth:CGFloat = minimumTextWrapWidth * 0.1
        var textHeight:CGFloat = self.height(withConstrainedWidth: textWidth, font: font)

        //Increase width by 10% of minimumTextWrapWidth until minimum width found that makes the text fit within the specified height
        while textHeight > height {
            textWidth += incrementWidth
            textHeight = self.height(withConstrainedWidth: textWidth, font: font)
        }
        return ceil(textWidth)
    }
}

1
কি minimumTextWrapWidth:CGFloat?
ভাইচাস্লাভ গেরচিকভ

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

0

লেবেল পাঠ্যের উচ্চতা চেক করুন এবং এটি এতে কাজ করছে

let labelTextSize = ((labelDescription.text)! as NSString).boundingRect(
                with: CGSize(width: labelDescription.frame.width, height: .greatestFiniteMagnitude),
                options: .usesLineFragmentOrigin,
                attributes: [.font: labelDescription.font],
                context: nil).size
            if labelTextSize.height > labelDescription.bounds.height {
                viewMoreOrLess.hide(byHeight: false)
                viewLess.hide(byHeight: false)
            }
            else {
                viewMoreOrLess.hide(byHeight: true)
                viewLess.hide(byHeight: true)

            }

0

এই সমাধান রানটাইমের সময় উচ্চতা এবং প্রস্থ গণনা করতে সহায়তা করবে।

    let messageText = "Your Text String"
    let size = CGSize.init(width: 250, height: 1000)
    let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
    let estimateFrame = NSString(string: messageText).boundingRect(with:  size, options: options, attributes: [NSAttributedString.Key.font: UIFont(name: "HelveticaNeue", size: 17)!], context: nil)

এখানে আপনি আনুমানিক উচ্চতা গণনা করতে পারেন যে আপনার স্ট্রিংটি এটি গ্রহণ করবে এবং এটি ইউআইএলবেল ফ্রেমে স্থান দেবে।

estimateFrame.Width
estimateFrame.Height 

0

সুইফট 5:

আপনার যদি ইউআইএলবেল থাকে এবং কোনওভাবেই বাউন্ডিং রেক্ট আপনার পক্ষে কাজ করে না (আমি এই সমস্যার মুখোমুখি হয়েছি It এটি সর্বদা 1 লাইন উচ্চতা ফেরত)

extension UILabel {
    func getSize(constrainedWidth: CGFloat) -> CGSize {
        return systemLayoutSizeFitting(CGSize(width: constrainedWidth, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
    }
}

আপনি এটি এর মতো ব্যবহার করতে পারেন:

let label = UILabel()
label.text = "My text\nIs\nAwesome"
let labelSize = label.getSize(constrainedWidth:200.0)

আমার জন্য কাজ কর


-2
@IBOutlet weak var constraintTxtV: NSLayoutConstraint!
func TextViewDynamicallyIncreaseSize() {
    let contentSize = self.txtVDetails.sizeThatFits(self.txtVDetails.bounds.size)
    let higntcons = contentSize.height
    constraintTxtV.constant = higntcons
}

5
আপনার উত্তরটিতে কেবল কোড নয়, কোড সম্পর্কিত একটি ব্যাখ্যাও থাকা উচিত। দয়া করে দেখুন কিভাবে উত্তর দিতে আরো বিস্তারিত জানার জন্য।
MechMK1

এই কোডটি প্রশ্নের উত্তর দিতে পারে, কেন এবং / অথবা এই কোডটির প্রশ্নের উত্তর কীভাবে তার দীর্ঘমেয়াদী মানকে উন্নত করে সে সম্পর্কে অতিরিক্ত প্রসঙ্গ সরবরাহ করে।
ইসমা

এই উত্তরটি অসম্পূর্ণ। এটি গুরুত্বপূর্ণ ভেরিয়েবলগুলি বোঝায় যারা প্রকারগুলি অজানা যা উদ্দেশ্যকে পরাস্ত করে
বিটউইট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.