এনএসএট্রিবিউটেড স্ট্রিংয়ের জন্য বাউন্ডিংরেক্টটইথসাইজ ভুল আকারে ফিরে আসছে


151

আমি একটি বিশিষ্ট স্ট্রিংয়ের জন্য রেকটটি পাওয়ার চেষ্টা করছি, তবে বাউন্ডিংরেক্টউইথসাইজ কলটি আমি যে আকারটি পাস করে সেটিকে সম্মান করে না এবং একটি বৃহত্তর উচ্চতার বিপরীতে (এটি একটি দীর্ঘ স্ট্রিং) বিপরীতে একটি রেখার উচ্চতা সহ একটি রেক্টর ফিরিয়ে দিচ্ছে। আমি উচ্চতার জন্য খুব বড় মান এবং নীচের কোডের মতো 0 অনুসারে পরীক্ষণ করেছি, তবে ফিরে পাওয়া রেটটি সবসময় একই থাকে।

CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(300,0.0)
  options:NSStringDrawingUsesDeviceMetrics
  context:nil];

এটি কি ভাঙা, না মোড়ানো পাঠ্যের জন্য এটি একটি রেকট ফিরিয়ে দেওয়ার জন্য আমার অন্য কিছু করা দরকার?


5
আপনি কি কাটা / ক্লিপিং সঙ্গে অনুচ্ছেদে শৈলী আছে lineBreakMode?
danyowdee

1
যদি এই কারণ UILabel পরিমাপ পড়ছেন / একটি ভুল প্রস্থের সাথে মোড়ানো কটাক্ষপাত করা stackoverflow.com/questions/46200027/... । বিশেষত, অ্যাপ্লিকেশন লঞ্চে এনএসএল্লোস ডিফল্টলাইনব্র্যাকস্ট্রিটিকে মিথ্যা হিসাবে সেট করা।
এরিক

উত্তর:


312

দেখে মনে হচ্ছে আপনি সঠিক বিকল্প সরবরাহ করছেন না। মোড়ানো লেবেলের জন্য, কমপক্ষে সরবরাহ করুন:

CGRect paragraphRect =
  [attributedText boundingRectWithSize:CGSizeMake(300.f, CGFLOAT_MAX)
  options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
  context:nil];

দ্রষ্টব্য: যদি মূল পাঠ্যের প্রস্থটি 300 এর নীচে থাকে তবে লাইন মোড়ানো হবে না, সুতরাং আবদ্ধ আকারটি সঠিক কিনা তা নিশ্চিত করুন, অন্যথায় আপনি এখনও ভুল ফলাফল পাবেন।


25
প্রত্যেককে এই উত্তরটি দেখার দরকার কারণ এটি কার্যকর। সম্ভবত এই পদ্ধতির জন্য পরিষ্কার ডকুমেন্টেশন প্রয়োজন এবং সাধারণভাবে স্ট্রিং স্ট্রিংগুলি; আপনার কোথায় নজর দেওয়া দরকার তা স্পষ্ট নয়।
ম্যাকসার্ভ

31
মনোযোগ! এটা সবসময় কাজ করে না! কখনও কখনও ফিরে আসা প্রস্থ আকার পরামিতি প্রস্থের চেয়ে বড় হয়। এমনকি আপেল পদ্ধতি নথির বিবরণে বলা হয়েছে: "আকারের পরামিতিগুলিতে আপনি যে সীমাবদ্ধতাগুলি নির্দিষ্ট করেছেন সেগুলি স্ট্রিংকে কীভাবে আকার দিতে হবে সে জন্য রেন্ডারারের জন্য গাইড However তবে, এই পদ্ধতির দ্বারা প্রত্যাবর্তিত প্রকৃত বাউন্ডিং আয়তক্ষেত্রটি বাধাগুলির চেয়ে বড় হতে পারে যদি অতিরিক্ত স্থানের প্রয়োজন হয় পুরো স্ট্রিং রেন্ডার করুন। "
ক্লাস

75
এনএসএট্রিবিউটেড স্ট্রিং এবং বাউন্ডিং রেক্টউইথসাইজের জন্য এপিআই একেবারে চকচকে।
মলহাল

27
আর একটি গ্যাচা হ'ল অনুচ্ছেদে ফিরে আসা উচ্চতা (এবং সম্ভবত প্রস্থটি) প্রায়শই একটি ভগ্নাংশের মান। সুতরাং এটি উচ্চতা হিসাবে 141.3 বলে বেরিয়ে আসতে পারে। আপনার ফলাফলটি ceilf(paragraphRect.size.height)এমনভাবে ব্যবহার করা দরকার যাতে এটির চারপাশ। আমি এটি সর্বদা ভুলে যাই এবং কেন আমার লেবেলগুলি এখনও ক্লিপ করছে তা অবাক করে।
জামোন 2'14

39
আমি সর্বদা আমার boundingRectWithSize:গণনাগুলিকে সিজিআরেক্টইন্টেগ্রাল () এ মোড় করি যা CGRectIntegral rounds the rectangle’s origin downward and its size upward to the nearest whole integersএই ক্ষেত্রে উচ্চতা এবং প্রস্থকে চারদিকে ছড়িয়ে দেবে তা নিশ্চিত করার জন্য যদি উচ্চতা বা প্রস্থ একটি ভগ্নাংশের মান হয় তবে কোনও ক্লিপিং ঘটে না তা নিশ্চিত করে।
রানমেড

47

কিছু কারণে বাউন্ডিংরেটওয়েটসাইজ সর্বদা ভুল আকার দেয়। আমি একটি সমাধান খুঁজে বের করেছি। ইউআইটেক্সটভিউ-সাইজ থ্যাটফিটগুলির জন্য একটি পদ্ধতি রয়েছে যা পাঠ্য সংস্থার জন্য যথাযথ আকার প্রদান করে। সুতরাং সীমানা রেকটউইথসাইজ ব্যবহারের পরিবর্তে, একটি এলোমেলো ফ্রেম সহ একটি ইউআইটিেক্সটভিউ তৈরি করুন এবং তার প্রস্থ এবং সিজিএফএলএএফএএমএক্স উচ্চতার সাথে এর আকারটিফিটগুলি কল করুন। এটি সঠিক উচ্চতা হবে এমন আকারটি দেয়।

   UITextView *view=[[UITextView alloc] initWithFrame:CGRectMake(0, 0, width, 10)];   
   view.text=text;
   CGSize size=[view sizeThatFits:CGSizeMake(width, CGFLOAT_MAX)];
   height=size.height; 

আপনি যদি কিছুক্ষণ লুপের মধ্যে আকারটি গণনা করছেন তবে কোনও অটোরিলিজ পুলে এটি যুক্ত করতে ভুলবেন না, কারণ সেখানে ইউআইটিএক্সটভিউয়ের সংখ্যা তৈরি হবে, আমরা অটোরেলেজপুল ব্যবহার না করলে অ্যাপটির রানটাইম মেমরি বাড়বে।


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

আপনি কি মনে করেন না যে পদ্ধতিটি বলা যেতে পারে UITextViewতত বেশি সময় তৈরি করা ওভারকিল heightForRowAtIndexPath? এটি সময় নেয়
Josnos

আমি আপনার সাথে @ জিনোসকে সম্মত করছি, তবে এটিই ছিল আমার জন্য একমাত্র সমাধান worked
27

বিটিডব্লিউ আমি যথাযথ সমাধান চেয়েছি: স্ট্যাকওভারফ্লো.com
জেনোস

এটিই একমাত্র সমাধান যা কাজ করে। এই সমস্যাটি 9 বছর হয়েছে এবং অ্যাপল স্পষ্টতই এটি সমাধান করতে চান না বা তাদের প্রকৌশলীরা এটির জন্য কোনও সমাধান বের করতে দুর্বল হতে হবে। আমরা এখানে iOS 11 সম্পর্কে কথা বলছি, এখনও একই বাগটি বহন করছি।
হাঁস

31

এড ম্যাকম্যানাস অবশ্যই এটি কাজ করার জন্য একটি চাবিকাঠি সরবরাহ করেছে। আমি একটি মামলা পেয়েছি যা কাজ করে না

UIFont *font = ...
UIColor *color = ...
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                     font, NSFontAttributeName,
                                     color, NSForegroundColorAttributeName,
                                     nil];

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString: someString attributes:attributesDictionary];

[string appendAttributedString: [[NSAttributedString alloc] initWithString: anotherString];

CGRect rect = [string boundingRectWithSize:constraint options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];

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


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

3
মনে রাখবেন যে এটিও উপস্থিত হয় যে আলাদা আলাদা এনএসএট্রিবিউটেড স্ট্রিংসগুলি যে কোনও একটি তৈরির জন্য সংযুক্ত করা হয়েছে সেগুলি অবশ্যই RameWithSize কে সঠিকভাবে কাজ করতে বাউন্ডিংয়ের জন্য একই শব্দ অভিধান (এবং এইভাবে একই ফন্ট) ব্যবহার করতে হবে!
বেন হুইলার 18

1
এই সমাধানটি আমার ইউআইএলবেল বিভাগের জন্য "সঙ্কুচিত হতে উপযুক্ত" এর মতো একটির সাথে সাদৃশ্যপূর্ণ। এটি কাজ করার জন্য আমার চাবিকাঠিটি ছিল FLT_MAX উচ্চতার সাথে সীমাবদ্ধ আয়তক্ষেত্র তৈরি করা। তা না হলে, আমি কেবল একটি লাইনের জন্য একটি আয়তক্ষেত্র পেয়ে যাব বলে মনে হচ্ছে।
dre1138

চারদিকে +1 এটি সত্যিই আমাকে পেয়েছে, তাই ছেলেরা এটি কাজ করার জন্য ধন্যবাদ।
ওয়েক্স 16

আমার এই সমস্যা ছিল আমি NSMutableAttributedStringকোনও বৈশিষ্ট্য ছাড়াই স্পেস এবং নিউলাইনগুলি ব্যবহার করেছি এবং আমি ভুল আকার পাচ্ছিলাম।
vbezhenar

28

দীর্ঘ তদন্তের পরে আমার চূড়ান্ত সিদ্ধান্ত:
- boundingRectWithSizeকেবলমাত্র অক্ষরগুলির নিরবচ্ছিন্ন ক্রমের জন্য ফাংশনটি সঠিক আকার দেয়! যদি স্ট্রিংয়ে ফাঁকা জায়গা বা অন্য কিছু থাকে (অ্যাপল "গ্লাইফগুলির কিছু" বলে ডাকা হয়) - পাঠ্যটি প্রদর্শনের জন্য প্রয়োজনীয় রেকটটির প্রকৃত আকার পাওয়া অসম্ভব!
আমি অক্ষরে অক্ষরে আমার স্ট্রিংগুলিতে স্থানগুলি প্রতিস্থাপন করেছি এবং অবিলম্বে সঠিক ফলাফল পেয়েছি।

অ্যাপল এখানে বলেছে: https://developer.apple.com/docamentation/foundation/nsstring/1524729- সীমানা রক্ষণাবেক্ষণের সাথে

"এই পদ্ধতিটি স্ট্রাইজে গ্লাইফগুলির আসল সীমানা ফেরত দেয় Some কিছু গ্লাইফ (উদাহরণস্বরূপ) পাস করা আকার দ্বারা নির্দিষ্ট বিন্যাসের সীমাবদ্ধতাগুলিকে ওভারল্যাপ করার অনুমতি দেয়, তাই কিছু ক্ষেত্রে আকারের উপাদানটির প্রস্থের মান প্রত্যাবর্তিত CGRectআকারের প্যারামিটারের প্রস্থের মান অতিক্রম করতে পারে।

সুতরাং প্রকৃত রেকর্ড গণনা করার জন্য আরও কিছু উপায় খুঁজে বের করা প্রয়োজন ...


দীর্ঘ তদন্ত প্রক্রিয়া সমাধানের পরে অবশেষে পাওয়া গেল !!! আমি নিশ্চিত না যে এটি সম্পর্কিত সমস্ত ক্ষেত্রে ভাল কাজ করবে UITextView, তবে মূল এবং গুরুত্বপূর্ণ জিনিসটি সনাক্ত হয়েছিল!

boundingRectWithSizeফাংশন পাশাপাশি CTFramesetterSuggestFrameSizeWithConstraints(এবং অন্যান্য অনেক পদ্ধতি) সঠিক আয়তক্ষেত্র ব্যবহার করা হলে আকার এবং পাঠ্যের অংশটি সঠিক গণনা করবে। উদাহরণস্বরূপ - UITextViewরয়েছে textView.bounds.size.width- এবং পাঠ্য অঙ্কন চলাকালীন এই মানটি সিস্টেম দ্বারা ব্যবহৃত প্রকৃত আয়তক্ষেত্র নয় UITextView

আমি খুব আকর্ষণীয় প্যারামিটার পেয়েছি এবং কোডে সহজ গণনা সম্পাদন করেছি:

CGFloat padding = textView.textContainer.lineFragmentPadding;  
CGFloat  actualPageWidth = textView.bounds.size.width - padding * 2;

এবং যাদু কাজ করে - আমার সমস্ত পাঠ্য এখনই গণনা করা হয়েছে! উপভোগ করুন!


1
হ্যাঁ, আমি এটিও লক্ষ্য করেছি, এটি প্রস্থের জন্য বাধা রাখে না, এটি সর্বদা বড় হয়। এটি সত্যিই দুর্দান্ত নয়, তারা কাজের পদ্ধতিটিকে অবমূল্যায়ন করেছে এবং এখন আমাদের এই বকাবকি মোকাবেলা করতে হবে।
বরিস গফুরভ

1
আপনি স্যার, আমার নতুন নায়ক! এটি আমাকে পাগল করে চলেছে। আমি টেক্সট কনটেনার্স ইনসেটগুলি সেট করছি, সুতরাং পাঠ্য ভিউ.বাউন্ডস.সাইজ.উইডিএইচটির পরিবর্তে টেক্সটভিউ.টেক্সটকন্টেইনার.সাইজ.উইথ ব্যবহার করতে হয়েছিল।
GCBenson

আমি এটি যথেষ্ট ভোট দিতে পারিনি। এত অদ্ভুত যে সীমাবদ্ধতা গণনার ক্ষেত্রে শূন্যস্থান বিবেচনা করা হয় না।
চেজ হল্যান্ড

1
"3" এর মতো কিছু ডামি চরিত্রের সাথে স্পেসগুলি প্রতিস্থাপন করে যথাযথ উচ্চতা ফিরে আসে
আবুজার আমিন

1
এটি আমার ক্যারিয়ার এবং কিউএ দলের সাথে আমার সম্পর্ককে বাঁচিয়েছিল। আমি তোমার কাছে একজন বিয়ার মানুষ !!ণী !!
lucaslt89

14

সুইফট চারটি সংস্করণ

let string = "A great test string."
let font = UIFont.systemFont(ofSize: 14)
let attributes: [NSAttributedStringKey: Any] = [.font: font]
let attributedString = NSAttributedString(string: string, attributes: attributes)
let largestSize = CGSize(width: bounds.width, height: .greatestFiniteMagnitude)

//Option one (best option)
let framesetter = CTFramesetterCreateWithAttributedString(attributedString)
let textSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRange(), nil, largestSize, nil)

//Option two
let textSize = (string as NSString).boundingRect(with: largestSize, options: [.usesLineFragmentOrigin , .usesFontLeading], attributes: attributes, context: nil).size

//Option three
let textSize = attributedString.boundingRect(with: largestSize, options: [.usesLineFragmentOrigin , .usesFontLeading], context: nil).size

সিটিফ্রেমেসেটরের সাহায্যে পাঠ্যটি পরিমাপ করা সবচেয়ে ভাল কাজ করে কারণ এটি পূর্ণসংখ্যার মাপ সরবরাহ করে এবং ইমোজি এবং অন্যান্য ইউনিকোড অক্ষরকে হ্যান্ডল করে।


10

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

NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(width, CGFLOAT_MAX)];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[layoutManager addTextContainer:textContainer];

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:formattedString];
[textStorage addLayoutManager:layoutManager];

const CGFloat formattedStringHeight = ceilf([layoutManager usedRectForTextContainer:textContainer].size.height);

এটি ইউনিকোড বিন্দু নাও থাকতে পারে, এটি আপনার স্ট্রিংয়ের শেষে ফাঁকা স্থান হতে পারে। উপরের উত্তরটি দেখুন: stackoverflow.com/a/25941139/337934
স্যামবি

9

আপনি যদি লেজ কেটে কেটে বাউন্ডিং বক্স পেতে চান তবে এই প্রশ্ন আপনাকে সাহায্য করতে পারে।

CGFloat maxTitleWidth = 200;

NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = NSLineBreakByTruncatingTail;

NSDictionary *attributes = @{NSFontAttributeName : self.textLabel.font,
                             NSParagraphStyleAttributeName: paragraph};

CGRect box = [self.textLabel.text
              boundingRectWithSize:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)
              options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
              attributes:attributes context:nil];

9

দেখা যাচ্ছে যে এনএসএট্রিবিউটেড স্ট্রিংয়ের প্রতিটি অংশে কমপক্ষে এনএসফন্টআট্রিবিউটনেম এবং এনএসফোরগ্রাউন্ডক্লোরঅ্যাট্রিবিউটনাম সেট সহ একটি অভিধান সেট থাকতে হবে, যদি আপনি বাউন্ডিং রেক্ট উইথসাইজকে আসলে কাজ করতে চান!

আমি সেই নথিটি কোথাও দেখতে পাচ্ছি না।


ধন্যবাদ, এটিই আমার জন্য সমাধান ছিল, কেবলমাত্র আমি খুঁজে পেয়েছি যে কেবল এনএসফন্টঅ্যাট্রিবিউটের নামই প্রয়োজনীয় ছিল, এনএসফোরগ্রাউন্ডকালারঅ্যাট্রিবিউটনেম নয়
মার্ময়

7

@warrenm দুঃখিত যে ফ্রেমসেটর পদ্ধতিটি আমার পক্ষে কার্যকর হয়নি work

আমি এটি পেয়েছি his এই ফাংশনটি প্রদত্ত প্রস্থের জন্য আইফোন / আইপ্যাড এসডিকে এনএসএট্রিবিউটেড স্ট্রিংয়ের একটি স্ট্রিং রেঞ্জের জন্য প্রয়োজনীয় ফ্রেমের আকার নির্ধারণ করতে আমাদের সহায়তা করতে পারে:

এটি ইউআইটিবেবল ভিউ সেলগুলির গতিশীল উচ্চতার জন্য ব্যবহার করা যেতে পারে

- (CGSize)frameSizeForAttributedString:(NSAttributedString *)attributedString
{
    CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
    CGFloat width = YOUR_FIXED_WIDTH;

    CFIndex offset = 0, length;
    CGFloat y = 0;
    do {
        length = CTTypesetterSuggestLineBreak(typesetter, offset, width);
        CTLineRef line = CTTypesetterCreateLine(typesetter, CFRangeMake(offset, length));

        CGFloat ascent, descent, leading;
        CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

        CFRelease(line);

        offset += length;
        y += ascent + descent + leading;
    } while (offset < [attributedString length]);

    CFRelease(typesetter);

    return CGSizeMake(width, ceil(y));
}

হ্যাডাড আইএসএসএ >>> http://haddadissa.blogspot.in/2010/09/compute-needed-heigh-for-fixed-width-of.html ধন্যবাদ


কোনও ডিভাইসে আমার পক্ষে কাজ করে না (আইফোন 4 এবং 5)। IOS8.3 সঙ্গে iOS7.1.2 এবং 4S সিমুলেটার সঙ্গে :( ডিভাইসে উভয়
সানজানা

এই কোন আমদানি প্রয়োজন?
jose920405

@ করণআলাঙ্গাত হ্যাঁ#import <CoreText/CoreText.h>
জোস 920405

7

আমি খুঁজে পেয়েছি যে পছন্দসই সমাধানটি লাইন ব্রেকগুলি পরিচালনা করে না।

আমি দেখতে পেয়েছি যে এই পদ্ধতিটি সব ক্ষেত্রেই কাজ করে:

UILabel* dummyLabel = [UILabel new];
[dummyLabel setFrame:CGRectMake(0, 0, desiredWidth, CGFLOAT_MAX)];
dummyLabel.numberOfLines = 0;
[dummyLabel setLineBreakMode:NSLineBreakByWordWrapping];
dummyLabel.attributedText = myString;
[dummyLabel sizeToFit];
CGSize requiredSize = dummyLabel.frame.size;

আমার ক্ষেত্রে আমার পটভূমি থ্রেডে গণনা করা উচিত, এবং ইউআই উপাদান ব্যবহারের অনুমতি নেই
লুবো

4

এই কৌশলগুলি ব্যবহার করে সঠিক আকার না পাওয়ার ক্ষেত্রে আমার একই সমস্যা ছিল এবং আমি এটি কার্যকর করার জন্য আমার দৃষ্টিভঙ্গি পরিবর্তন করেছি।

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

আমি মনে করি যদি আমার উচ্চতা নির্ভরযোগ্যভাবে পাওয়ার দরকার হয় তবে আমি এমন একটি ভিউ তৈরি করব যা লুকানো এবং এই প্রতিবন্ধকতাগুলি সীমাবদ্ধতা প্রয়োগ হয়ে গেলে ফ্রেমের উচ্চতা পেয়ে যায় get


2
আপনি এটি প্রদর্শনের জন্য একটি কোড নমুনা যুক্ত করতে পারেন? ধন্যবাদ.
নাথান বাগুগিয়া

3

আমি গেমটি থেকে একটু দেরি করেছি - তবে আমি এমন একটি উপায় বের করার চেষ্টা করছিলাম যা সন্ধানকারীটিতে কোনও ফাইল সম্পাদনা করার মতো একটি ফোকাস রিং তৈরির জন্য একটি নির্দিষ্ট বৈশিষ্ট্যযুক্ত স্ট্রিংয়ের চারপাশে ফিট করে এমন বাউন্ডিং বক্সটি সন্ধান করতে কাজ করে। স্ট্রিংয়ের শেষে ফাঁকা স্থান বা স্ট্রিংয়ের অভ্যন্তরে একাধিক স্পেস থাকা অবস্থায় আমি যা চেষ্টা করেছি তা ব্যর্থ হয়েছে। boundingRectWithSizeএটির পাশাপাশি খারাপভাবে ব্যর্থ হয় CTFramesetterCreateWithAttributedString

NSLayoutManagerনীচের কোডটি ব্যবহার করে মনে হচ্ছে যে আমি এখনও অবধি খুঁজে পেয়েছি তার সব ক্ষেত্রেই কৌশলটি করা হয়েছে এবং একটি রেক্টর প্রদান করে যা পুরোপুরি স্ট্রিংয়ের সাথে আবদ্ধ। বোনাস: আপনি যদি পাঠ্যটি নির্বাচন করেন তবে নির্বাচনের প্রান্তগুলি ঠিক ফিরে আসা আয়ত্তের সীমানা পর্যন্ত যায়। নীচের কোডটি একটি থেকে লেআউট ম্যানেজার ব্যবহার করে NSTextView

NSLayoutManager* layout = [self layoutManager];
NSTextContainer* container = [self textContainer];

CGRect focusRingFrame = [layout boundingRectForGlyphRange:NSMakeRange(0, [[self textStorage] length]) inTextContainer:container];

2
textView.textContainerInset = UIEdgeInsetsZero;
NSString *string = @"Some string";
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:12.0f], NSForegroundColorAttributeName:[UIColor blackColor]};
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
[textView setAttributedText:attributedString];
CGRect textViewFrame = [textView.attributedText boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.view.frame)-8.0f, 9999.0f) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];
NSLog(@"%f", ceilf(textViewFrame.size.height));

নিখুঁতভাবে সব ফন্টে কাজ করে!


1

আমারও একই সমস্যা ছিল, তবে আমি স্বীকার করেছি যে উচ্চতার প্রতিবন্ধকতা সঠিকভাবে সেট করা হয়েছে। সুতরাং আমি নিম্নলিখিতটি করেছেন:

-(CGSize)MaxHeighForTextInRow:(NSString *)RowText width:(float)UITextviewWidth {

    CGSize constrainedSize = CGSizeMake(UITextviewWidth, CGFLOAT_MAX);

    NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                          [UIFont fontWithName:@"HelveticaNeue" size:11.0], NSFontAttributeName,
                                          nil];

    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:RowText attributes:attributesDictionary];

    CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];

    if (requiredHeight.size.width > UITextviewWidth) {
        requiredHeight = CGRectMake(0, 0, UITextviewWidth, requiredHeight.size.height);
    }

    return requiredHeight.size;
}

1
    NSDictionary *stringAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont systemFontOfSize:18], NSFontAttributeName,
                                      [UIColor blackColor], NSForegroundColorAttributeName,
                                      nil];

    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:myLabel.text attributes:stringAttributes];
    myLabel.attributedText = attributedString; //this is the key!

    CGSize maximumLabelSize = CGSizeMake (screenRect.size.width - 40, CGFLOAT_MAX);

    CGRect newRect = [myLabel.text boundingRectWithSize:maximumLabelSize
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:stringAttributes context:nil];

    self.myLabelHeightConstraint.constant = ceilf(newRect.size.height);

আমি এই পৃষ্ঠায় সমস্ত কিছু চেষ্টা করেছিলাম এবং এখনও একটি ইউআইএলবেলের একটি মামলা রয়েছে যা সঠিকভাবে ফর্ম্যাটেড হচ্ছে না। আসলে লেবেলে অ্যাট্রিবিউটটেক্সট সেট করা অবশেষে সমস্যাটি স্থির করে।


1

একটি জিনিস আমি লক্ষ্য করছিলাম তা হচ্ছে যে আয়ত্তটি ফিরে আসবে সেটির মধ্যে আমি যেটা পেরিয়েছি তার (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)contextচেয়ে প্রস্থটি আরও প্রশস্ত হবে this আমি এটি এর মতো সমাধান করেছি:

NSString *aLongString = ...
NSInteger width = //some width;            
UIFont *font = //your font;
CGRect rect = [aLongString boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                        options:(NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin)
                                     attributes:@{ NSFontAttributeName : font,
                                                   NSForegroundColorAttributeName : [UIColor whiteColor]}
                                        context:nil];

if(rect.size.width > width)
{
    return rect.size.height + font.lineHeight;
}
return rect.size.height;

আরও কিছু প্রসঙ্গে; আমার মাল্টি লাইন পাঠ্য ছিল এবং আমি এটি প্রদর্শন করার জন্য সঠিক উচ্চতা সন্ধান করার চেষ্টা করছিলাম bound কাটা হবে। যখন বাউন্ডারিটিং উইথসাইজে ভুল প্রস্থ ব্যবহার করা হয়েছিল তখন পরীক্ষার সময় থেকে উচ্চতাটি 1 লাইনের দ্বারা সংক্ষিপ্ত করে তুলবে। সুতরাং আমি চেক করব যে প্রস্থটি বেশি ছিল কিনা এবং যদি তাই হয় তবে কাটা কাটা এড়াতে পর্যাপ্ত স্থান সরবরাহ করতে হরফের লাইন হাইট যুক্ত করুন।


প্রস্থের সাথে রেখার উচ্চতা কীভাবে প্রভাব ফেলছে?
রুই মুলিয়া

@ রুইমুলিয়া লাইনের উচ্চতা প্রস্থকে প্রভাবিত করে না। এটি কীভাবে আমার বাগটি স্থির করেছে সে সম্পর্কে আরও প্রসঙ্গ সরবরাহ করার জন্য আমি আমার উত্তর আপডেট করেছি।
অষ্টম

0
    NSAttributedString *attributedText =[[[NSAttributedString alloc]
                                          initWithString:joyMeComment.content
                                          attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:TextFont]}] autorelease];

    CGRect paragraphRect =
    [attributedText boundingRectWithSize:CGSizeMake(kWith, CGFLOAT_MAX)
                                 options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                 context:nil];
    contentSize = paragraphRect.size;

    contentSize.size.height+=10;
    label.frame=contentSize;

যদি লেবেলের ফ্রেম 10 যোগ না করে তবে এই পদ্ধতিটি কখনও কাজ করবে না! আশা করি এটি আপনাকে সহায়তা করতে পারে! সৌভাগ্য.


0
Add Following methods in ur code for getting correct size of attribute string 
1.
    - (CGFloat)findHeightForText:(NSAttributedString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font
 {
    UITextView *textView = [[UITextView alloc] init];
    [textView setAttributedText:text];
    [textView setFont:font];
    CGSize size = [textView sizeThatFits:CGSizeMake(widthValue, FLT_MAX)];
    return size.height;

}

2. Call on heightForRowAtIndexPath method
     int h = [self findHeightForText:attrString havingWidth:yourScreenWidth andFont:urFont];

আমার ক্ষেত্রে আমার পটভূমি থ্রেডে গণনা করা উচিত, এবং ইউআই উপাদান ব্যবহারের অনুমতি নেই
লুবো

0

আমি আমার চিন্তা যুক্ত করতে চাই যেহেতু আমার ঠিক একই সমস্যা ছিল had

আমি ব্যবহার করছিলাম UITextViewযেহেতু এটিতে ভাল টেক্সট প্রান্তিককরণ ছিল (ন্যায্যতা, যা সেই সময়ে পাওয়া যায়নি UILabel) তবে অ-ইন্টারেক্টিভ-অ-স্ক্রোলযোগ্য "অনুকরণ" করার জন্য UILabel, আমি সম্পূর্ণ স্ক্রোলিং, বাউন্সিং এবং ব্যবহারকারীর মিথস্ক্রিয়া বন্ধ করেছিলাম ।

অবশ্যই সমস্যাটি ছিল পাঠ্যটি গতিশীল ছিল এবং প্রস্থটি স্থির করা হওয়ার সাথে সাথে আমি যখনই নতুন পাঠ্য মানটি সেট করেছিলাম তখনই উচ্চতাটি পুনরায় গণনা করা উচিত।

boundingRectWithSizeআমার পক্ষে মোটেও ভাল কাজ হয়নি, যা আমি দেখতে পাচ্ছিলাম UITextViewতার উপর থেকে কিছুটা মার্জিন যুক্ত করা যা boundingRectWithSizeকোনও গণনাতে নামবে না, সুতরাং, থেকে উদ্ধার করা উচ্চতা boundingRectWithSizeতার চেয়ে কম ছিল।

যেহেতু পাঠ্যটি দ্রুত আপডেট করা যাচ্ছিল না, এটি কেবলমাত্র কিছু তথ্যের জন্য ব্যবহৃত হয়েছে যা প্রতি ২-৩ সেকেন্ডে সর্বাধিক আপডেট হতে পারে, আমি নিম্নলিখিত পদ্ধতির সিদ্ধান্ত নিয়েছি:

/* This f is nested in a custom UIView-inherited class that is built using xib file */
-(void) setTextAndAutoSize:(NSString*)text inTextView:(UITextView*)tv
{
    CGFloat msgWidth = tv.frame.size.width; // get target's width

    // Make "test" UITextView to calculate correct size
    UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, msgWidth, 300)]; // we set some height, really doesn't matter, just put some value like this one.
    // Set all font and text related parameters to be exact as the ones in targeted text view
    [temp setFont:tv.font];
    [temp setTextAlignment:tv.textAlignment];
    [temp setTextColor:tv.textColor];
    [temp setText:text];

    // Ask for size that fits :P
    CGSize tv_size = [temp sizeThatFits:CGSizeMake(msgWidth, 300)];

    // kill this "test" UITextView, it's purpose is over
    [temp release];
    temp = nil;

    // apply calculated size. if calcualted width differs, I choose to ignore it anyway and use only height because I want to have width absolutely fixed to designed value
    tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, msgWidth, tv_size.height );
}

* উপরের কোডটি সরাসরি আমার উত্স থেকে অনুলিপি করা হয়নি, আমাকে এটিকে সামঞ্জস্য করতে হয়েছিল / এই নিবন্ধটির জন্য প্রয়োজনীয় অন্যান্য সামগ্রীর গুচ্ছ থেকে সাফ করতে হবে। এটি কপি-পেস্ট এবং এটি-উইল-ওয়ার্ক-কোডের জন্য নেবেন না।

স্পষ্টত অসুবিধা হ'ল এটি প্রতিটি কলের জন্য বরাদ্দ এবং প্রকাশ করেছে।

তবে, সুবিধাটি হ'ল আপনি কীভাবে বাউন্ডরিং রেক্টউইথসাইজ পাঠ্যটি আঁকেন এবং এর আকার এবং টেক্সট অঙ্কনটির প্রয়োগকরণ UITextView(বা UILabelযা আপনি কেবল এটির UITextViewসাথে প্রতিস্থাপন ব্যবহার করতে পারেন UILabel) গণনা করে তার মধ্যে সামঞ্জস্যতার উপর নির্ভর করে এড়িয়ে যান । অ্যাপলের যে কোনও "বাগ" এড়ানো যেতে পারে।

পিএস মনে হচ্ছে আপনার এই "টেম্প" প্রয়োজন হবে না UITextViewএবং কেবল sizeThatFitsলক্ষ্য থেকে সরাসরি জিজ্ঞাসা করতে পারেন , তবে এটি আমার পক্ষে কার্যকর হয়নি। যদিও যুক্তি বলবে এটি কাজ করা উচিত এবং অস্থায়ী বরাদ্দ / প্রকাশের UITextViewপ্রয়োজন হয় না, এটি হয়নি। তবে এই সমাধানটি আমি যে কোনও পাঠ্যকে সেট করব তার জন্য নির্দোষভাবে কাজ করেছে।


আমার ক্ষেত্রে আমার পটভূমি থ্রেডে গণনা করা উচিত, এবং ইউআই উপাদান ব্যবহারের অনুমতি নেই
লুবো

0

ঠিক আছে তাই আমি এটিকে ডিবাগ করতে প্রচুর সময় ব্যয় করেছি। আমি জানতে পেরেছি যে boundingRectWithSizeআমার দ্বারা পাঠ্য প্রদর্শন করার জন্য অনুমোদিত হিসাবে নির্ধারিত সর্বাধিক পাঠ্য উচ্চতা UITextViewফ্রেমের আকারের চেয়ে কম ছিল।

আমার ক্ষেত্রে ফ্রেম সর্বাধিক 140pt এ তবে ইউআইটিেক্সটভিউ বেশিরভাগ 131pt এ পাঠ্য সহ্য করে।

আমি এটি ম্যানুয়ালি খুঁজে বের করতে হয়েছিল এবং "আসল" সর্বাধিক উচ্চতাটিকে হার্ডকোড করেছি।

এখানে আমার সমাধান:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSString *proposedText = [textView.text stringByReplacingCharactersInRange:range withString:text];
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:proposedText];
    CGRect boundingRect;
    CGFloat maxFontSize = 100;
    CGFloat minFontSize = 30;
    CGFloat fontSize = maxFontSize + 1;
    BOOL fit;
    NSLog(@"Trying text: \"%@\"", proposedText);
    do {
        fontSize -= 1;
        //XXX Seems like trailing whitespaces count for 0. find a workaround
        [attributedText addAttribute:NSFontAttributeName value:[textView.font fontWithSize:fontSize] range:NSMakeRange(0, attributedText.length)];
        CGFloat padding = textView.textContainer.lineFragmentPadding;
        CGSize boundingSize = CGSizeMake(textView.frame.size.width - padding * 2, CGFLOAT_MAX);
        boundingRect = [attributedText boundingRectWithSize:boundingSize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil];
        NSLog(@"bounding rect for font %f is %@; (max is %f %f). Padding: %f", fontSize, NSStringFromCGRect(boundingRect), textView.frame.size.width, 148.0, padding);
        fit =  boundingRect.size.height <= 131;
    } while (!fit && fontSize > minFontSize);
    if (fit) {
        self.textView.font = [self.textView.font fontWithSize:fontSize];
        NSLog(@"Fit!");
    } else {
        NSLog(@"No fit");
    }
    return fit;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.