গতিশীল উচ্চতা রয়েছে এমন সারিগুলির সাথে ভিউ-ভিত্তিক এনএসটিবেল ভিউ


84

আমার এতে ভিউ-ভিত্তিক একটি অ্যাপ্লিকেশন রয়েছে NSTableView। এই সারণী দর্শনটির অভ্যন্তরে, আমার কাছে সারি রয়েছে NSTextFieldযেগুলিতে এমন সেল রয়েছে যা শব্দ-মোড়ানো সক্ষম করে একটি বহু-সারি সমন্বিত সামগ্রী রয়েছে । এর পাঠ্য সামগ্রীর উপর নির্ভর করে NSTextField, ঘরটি প্রদর্শনের জন্য প্রয়োজনীয় সারির আকার পৃথক হবে।

আমি জানি যে আমি NSTableViewDelegateপদ্ধতিটি প্রয়োগ করতে পারি - tableView:heightOfRow:উচ্চতা ফিরিয়ে আনতে, তবে উচ্চতাটি ব্যবহার করা শব্দ মোড়কের উপর ভিত্তি করে নির্ধারিত হবে NSTextField। এর মোড়ক শব্দটি NSTextFieldএকইভাবে কত প্রশস্ত NSTextField… এর প্রস্থের দ্বারা নির্ধারিত হয় এর উপর ভিত্তি করে NSTableView

Soooo… আমার ধারণা আমার প্রশ্ন… এটির জন্য একটি ভাল ডিজাইনের ধরণ কী? দেখে মনে হচ্ছে সবকিছুকেই আমি একত্রিত করায় বিশৃঙ্খলা সৃষ্টি করার চেষ্টা করছি। যেহেতু টেবিলভিউটি কোষগুলি তাদের বাইরে রাখার জন্য উচ্চতার জ্ঞান প্রয়োজন ... এবং NSTextFieldশব্দটি মোড়ানো নির্ধারণ করার জন্য এর বিন্যাসের প্রয়োজনীয় জ্ঞান প্রয়োজন ... এবং এর উচ্চতা নির্ধারণ করার জন্য কোষটি র‌্যাপ শব্দটির জ্ঞান প্রয়োজন ... এটি একটি বিজ্ঞপ্তি জগাখিচুড়ি ... এবং এটি আমাকে উন্মাদ করে চলেছে

পরামর্শ?

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

আগাম ধন্যবাদ!


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

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

@ জিভা: আপনি যদি এখনও এটি সমাধান করে থাকেন তবে ভাবছেন।
জোশুয়া নউজি

আমি অনুরূপ কিছু করার চেষ্টা করছি। আমি একটি এনএসটিেক্সটফিল্ড সাবক্লাসের ধারণা পছন্দ করি যা এটির নিজস্ব উচ্চতা সামঞ্জস্য করে। সেই উপশ্রেণীতে উচ্চতা পরিবর্তনের একটি (প্রতিনিধি) বিজ্ঞপ্তি যুক্ত করার এবং রূপরেখায় তথ্য পাওয়ার জন্য কিছু উপযুক্ত শ্রেণীর (ডেটা উত্স, রূপরেখা প্রতিনিধি, ...) দিয়ে পর্যবেক্ষণ করা কীভাবে?
জন ভেলম্যান

একটি অত্যন্ত সম্পর্কিত প্রশ্ন, উত্তরগুলির সাথে যা আমাকে এগুলির চেয়ে আরও বেশি সাহায্য করেছে: এনএসটিআরএলভিউ সারি উচ্চতা এনএসএসআরটিংয়ের উপর ভিত্তি করে
অ্যাশলে

উত্তর:


133

এটি একটি মুরগি এবং ডিমের সমস্যা। সারণির সারি উচ্চতা জানতে হবে কারণ এটি নির্ধারণ করে যে প্রদত্ত দর্শনটি কোথায় থাকবে। তবে আপনি ইতিমধ্যে একটি দৃশ্য দেখতে চান যাতে আপনি এটি সারি উচ্চতা নির্ধারণ করতে পারেন। তো, কোনটি আগে আসে?

উত্তরটি হ'ল NSTableCellViewউচ্চতার পরিমাপের জন্য বাড়তি (বা আপনি যে কোনও দৃশ্য যা আপনার "সেল ভিউ" হিসাবে ব্যবহার করছেন) প্রায় রাখার জন্য। ইন tableView:heightOfRow:প্রতিনিধি পদ্ধতি, 'সারি' এবং সেট আপনার মডেল এক্সেস objectValueউপর NSTableCellView। তারপরে দৃশ্যের প্রস্থটিকে আপনার টেবিলের প্রস্থ হতে সেট করুন এবং (তবে আপনি এটি করতে চান) সেই দর্শনটির জন্য প্রয়োজনীয় উচ্চতাটি নির্ধারণ করুন। মানটি ফেরত দিন।

noteHeightOfRowsWithIndexesChanged:ডেলিগেট পদ্ধতিতে কল করবেন না tableView:heightOfRow:বা viewForTableColumn:row:! এটি খারাপ, এবং মেগা-ঝামেলা ঘটাবে।

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

noteHeightOfRowsWithIndexesChanged:অ্যানিমেটগুলি ডিফল্টরূপে ভুলে যাবেন না । এনিমেট না করার জন্য:

[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0];
[tableView noteHeightOfRowsWithIndexesChanged:indexSet];
[NSAnimationContext endGrouping];

PS: আমি স্ট্যাক ওভারফ্লোয়ের চেয়ে অ্যাপল দেব ফোরামগুলিতে পোস্ট করা প্রশ্নগুলিতে বেশি প্রতিক্রিয়া জানাই।

পিএসএস: আমি ভিউ ভিত্তিক এনএসটিবেল ভিউ লিখেছি


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

"এই দৃশ্যের জন্য প্রয়োজনীয় উচ্চতাটি চিহ্নিত করুন that মানটি ফিরিয়ে দিন।" .. এটি আমার সমস্যা :(। আমি ভিউ-ভিত্তিক টেবিলভিউটি ব্যবহার করছি, এবং কীভাবে করব তা আমার কোনও ধারণা নেই!
মাইজিড

@ কর্বিন উত্তরের জন্য ধন্যবাদ, আমার অ্যাপটিতে এটি ছিল। তবে মাভেরিক্স সম্পর্কিত এটিতে আমি একটি সমস্যা পেয়েছি। যেহেতু আপনি স্পষ্টতই এই বিষয়ে পারদর্শী, তাই আপনি আমার প্রশ্নটি পরীক্ষা করে দেখতে কি আপত্তি করবেন? এখানে: stackoverflow.com/questions/20924141/…
অ্যালেক্স

4
@ কর্বিন কি এর জন্য একটি প্রাসঙ্গিক উত্তর আছে, তবে এনএসটিবেল ভিউজের সাথে অটো-লেআউট এবং সীমাবদ্ধতা ব্যবহার করছে? অটো-লেআউট সহ একটি সম্ভাব্য সমাধান রয়েছে; অনুমান করা হাইফটআরআউটএন্টেক্সপথ এপিআইগুলি (এটি কোকোতে নেই) ব্যতীত যথেষ্ট যথেষ্ট কিনা তা ভাবছেন
জেডএস

4
@ জেডএস: আমি অটো লেআউটটি ব্যবহার করছি এবং কর্বিনের উত্তর প্রয়োগ করেছি। ইন tableView:heightOfRow:, আমি সারিটির মানগুলির সাথে আমার অতিরিক্ত সেল ভিউ সেট আপ করেছি (আমার কাছে কেবল একটি কলাম রয়েছে), এবং ফিরে আসছি cellView.fittingSize.heightfittingSizeএকটি এনএসভিউ পদ্ধতি যা দেখার সীমাবদ্ধতাগুলি পূরণ করে এমন ন্যূনতম আকারের গণনা করে।
পিটার হোসে

43

এটি ম্যাকোস 10.13 এর সাথে অনেক সহজ হয়েছে .usesAutomaticRowHeights। বিশদগুলি এখানে: https://developer.apple.com/library/content/releasenotes/AppKit/RN-appKit/#10_13 ("এনএসটিএবলভিউ অটোমেটিক সারি হাইটস" শীর্ষক বিভাগে))

মূলত আপনি কেবল নিজের NSTableViewবা NSOutlineViewস্টোরিবোর্ড সম্পাদকটি নির্বাচন করুন এবং আকার পরিদর্শকের মধ্যে এই বিকল্পটি নির্বাচন করুন:

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

তারপরে আপনি NSTableCellViewসেলটিতে শীর্ষ এবং নীচের সীমাবদ্ধতাগুলি রাখার জন্য আপনার জিনিসটি সেট করলেন এবং আপনার ঘরটি স্বয়ংক্রিয়ভাবে ফিট হওয়ার জন্য পুনরায় আকার দেবে। কোন কোড প্রয়োজন!

আপনার অ্যাপ্লিকেশনটি heightOfRow( NSTableView) এবং heightOfRowByItem( NSOutlineView) এ নির্দিষ্ট কোনও উচ্চতা উপেক্ষা করবে । এই পদ্ধতিটি দিয়ে আপনি স্বয়ংক্রিয় বিন্যাসের সারিগুলির জন্য কী উচ্চতা গণনা করছেন তা দেখতে পারেন:

func outlineView(_ outlineView: NSOutlineView, didAdd rowView: NSTableRowView, forRow row: Int) {
  print(rowView.fittingSize.height)
}

@ টুফটিম: যদি আপনি সঠিক সীমাবদ্ধতাগুলি ব্যবহার করেন এবং আপনি যখন নিশ্চিত হন যে ডায়নামিক উচ্চতার সাথে প্রতিটি এনএসেক্সটফিল্ডের পছন্দসই প্রস্থটি সেট করা থাকে তবে স্বয়ংক্রিয়ভাবে সেট করা থাকে wra আরও দেখুন stackoverflow.com/questions/46890144/...
এলী

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

আমি একটি সারির জন্য একটি নির্দিষ্ট উচ্চতা ব্যবহার করেছি তবে এটি আমার পক্ষে কাজ করে না
কেন জিরা

4
এটি আমার জন্য কেন কাজ করে না তা নির্ধারণের কয়েক দিন পরে আমি আবিষ্কার করেছি: TableCellViewসম্পাদনাযোগ্য না হলে এটি কেবলমাত্র কাজ করে । বিষয়গুলি [আচরণ: সম্পাদনযোগ্য] বা বাইন্ডিংস পরিদর্শকগুলিতে পরীক্ষা করা হয় না [শর্তসাপেক্ষে সম্পাদনযোগ্য সেট করুন: হ্যাঁ]
asukasz

আমি কেবল আপনার টেবিল সেলে প্রকৃত উচ্চতার সীমাবদ্ধতা থাকা কতটা গুরুত্বপূর্ণ তা জোর দিয়ে বলতে চাই: খনিটি হয়নি, তাই ঘরের গণনাযোগ্য ফিটিংসাইজটি 0.0 ছিল এবং হতাশার ফলস্বরূপ।
সবুজ_কনাইট

9

কর্বিনের উত্তরের ভিত্তিতে (বিটিডব্লিউ ধন্যবাদ এ সম্পর্কে কিছু আলোকপাত করা):

সুইফট 3, ম্যাকোস 10.11 (এবং উপরে) এর জন্য অটো-লেআউট সহ ভিউ-ভিত্তিক এনএসটিএবল ভিউ

আমার সেটআপ: আমার একটি NSTableCellViewঅটো-লেআউট ব্যবহার করে তৈরি করা হয়েছে। এটিতে (অন্যান্য উপাদানগুলি ছাড়াও) একটি বহু-লাইন রয়েছে NSTextFieldযাতে 2 টি সারি থাকতে পারে। সুতরাং, পুরো ঘর দেখার উচ্চতা এই পাঠ্য ক্ষেত্রের উচ্চতার উপর নির্ভর করে।

আমি আপডেটটি টেবিলের দৃশ্যে দুটি সময় উচ্চতা আপডেট করতে বলি:

1) যখন টেবিল ভিউটির আকার পরিবর্তন করে:

func tableViewColumnDidResize(_ notification: Notification) {
        let allIndexes = IndexSet(integersIn: 0..<tableView.numberOfRows)
        tableView.noteHeightOfRows(withIndexesChanged: allIndexes)
}

2) যখন ডেটা মডেল অবজেক্ট পরিবর্তন হয়:

tableView.noteHeightOfRows(withIndexesChanged: changedIndexes)

এটি সারণী দর্শনটিকে নতুন সারি উচ্চতার জন্য প্রতিনিধি জিজ্ঞাসা করবে।

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {

    // Get data object for this row
    let entity = dataChangesController.entities[row]

    // Receive the appropriate cell identifier for your model object
    let cellViewIdentifier = tableCellViewIdentifier(for: entity)

    // We use an implicitly unwrapped optional to crash if we can't create a new cell view
    var cellView: NSTableCellView!

    // Check if we already have a cell view for this identifier
    if let savedView = savedTableCellViews[cellViewIdentifier] {
        cellView = savedView
    }
    // If not, create and cache one
    else if let view = tableView.make(withIdentifier: cellViewIdentifier, owner: nil) as? NSTableCellView {
        savedTableCellViews[cellViewIdentifier] = view
        cellView = view
    }

    // Set data object
    if let entityHandler = cellView as? DataEntityHandler {
        entityHandler.update(with: entity)
    }

    // Layout
    cellView.bounds.size.width = tableView.bounds.size.width
    cellView.needsLayout = true
    cellView.layoutSubtreeIfNeeded()

    let height = cellView.fittingSize.height

    // Make sure we return at least the table view height
    return height > tableView.rowHeight ? height : tableView.rowHeight
}

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

// We need to keep one cell view (per identifier) around
fileprivate var savedTableCellViews = [String : NSTableCellView]()

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


এটি সঠিক উত্তর। আপনার যদি একাধিক কলাম থাকে তবে আপনি কলামের প্রস্থে সীমা নির্ধারণ করতে চান, সারণির প্রস্থ নয়।
ভোজতো

এছাড়াও, আপনি সেট হিসাবে cellView.bounds.size.width = tableView.bounds.size.width, কম সংখ্যায় উচ্চতা পুনরায় সেট করা ভাল ধারণা। যদি আপনি এই ডামি ভিউটি পুনরায় ব্যবহার করার পরিকল্পনা করেন, এটিকে কম সংখ্যায় সেট করা ফিটিং আকারটি "রিসেট" করবে।
ভোজতো

7

যে কেউ আরও কোড চান, তার জন্য আমি ব্যবহার করা সম্পূর্ণ সমাধান এখানে। আমাকে সঠিক দিকে নির্দেশ করার জন্য কর্বিন ডান ধন্যবাদ।

আমার উচ্চতা কতটা ছিল তা সম্পর্কে NSTextViewআমার উচ্চতা নির্ধারণ করা প্রয়োজন NSTableViewCell

আমি আমার সাবক্লাসে NSViewControllerঅস্থায়ী কল করে একটি নতুন ঘর তৈরি করবoutlineView:viewForTableColumn:item:

- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
{
    NSTableColumn *tabCol = [[outlineView tableColumns] objectAtIndex:0];
    IBAnnotationTableViewCell *tableViewCell = (IBAnnotationTableViewCell*)[self outlineView:outlineView viewForTableColumn:tabCol item:item];
    float height = [tableViewCell getHeightOfCell];
    return height;
}

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    IBAnnotationTableViewCell *tableViewCell = [outlineView makeViewWithIdentifier:@"AnnotationTableViewCell" owner:self];
    PDFAnnotation *annotation = (PDFAnnotation *)item;
    [tableViewCell setupWithPDFAnnotation:annotation];
    return tableViewCell;
}

আমার মধ্যে IBAnnotationTableViewCellযা আমার ঘরের জন্য নিয়ামক (সাবক্লাস NSTableCellView) আমার একটি সেটআপ পদ্ধতি আছে

-(void)setupWithPDFAnnotation:(PDFAnnotation*)annotation;

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

-(float)getHeightOfCell
{
    return [self getHeightOfContentTextView] + 60;
}

-(float)getHeightOfContentTextView
{
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[self.contentTextView font],NSFontAttributeName,nil];
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:[self.contentTextView string] attributes:attributes];
    CGFloat height = [self heightForWidth: [self.contentTextView frame].size.width forString:attributedString];
    return height;
}

- (NSSize)sizeForWidth:(float)width height:(float)height forString:(NSAttributedString*)string
{
    NSInteger gNSStringGeometricsTypesetterBehavior = NSTypesetterLatestBehavior ;
    NSSize answer = NSZeroSize ;
    if ([string length] > 0) {
        // Checking for empty string is necessary since Layout Manager will give the nominal
        // height of one line if length is 0.  Our API specifies 0.0 for an empty string.
        NSSize size = NSMakeSize(width, height) ;
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:size] ;
        NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:string] ;
        NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init] ;
        [layoutManager addTextContainer:textContainer] ;
        [textStorage addLayoutManager:layoutManager] ;
        [layoutManager setHyphenationFactor:0.0] ;
        if (gNSStringGeometricsTypesetterBehavior != NSTypesetterLatestBehavior) {
            [layoutManager setTypesetterBehavior:gNSStringGeometricsTypesetterBehavior] ;
        }
        // NSLayoutManager is lazy, so we need the following kludge to force layout:
        [layoutManager glyphRangeForTextContainer:textContainer] ;

        answer = [layoutManager usedRectForTextContainer:textContainer].size ;

        // Adjust if there is extra height for the cursor
        NSSize extraLineSize = [layoutManager extraLineFragmentRect].size ;
        if (extraLineSize.height > 0) {
            answer.height -= extraLineSize.height ;
        }

        // In case we changed it above, set typesetterBehavior back
        // to the default value.
        gNSStringGeometricsTypesetterBehavior = NSTypesetterLatestBehavior ;
    }

    return answer ;
}

- (float)heightForWidth:(float)width forString:(NSAttributedString*)string
{
    return [self sizeForWidth:width height:FLT_MAX forString:string].height ;
}

উচ্চতাফোরউইথ কোথায়: স্ট্রিং: বাস্তবায়িত?
জেডএস

এর জন্যে দুঃখিত. উত্তরে এটি যুক্ত হয়েছে। আসল এসও পোস্টটি সন্ধান করার চেষ্টা করেছি আমি এটি পেয়েছি তবে এটি খুঁজে পেল না।
সুনকাস

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

আমি আমার সমস্যা সম্পর্কে এখানে একটি প্রশ্ন পোস্ট করেছি: স্ট্যাকওভারফ্লো /
জেডএস

3

আমি বেশ কিছুদিন ধরে সমাধানের সন্ধান করছিলাম এবং নিম্নলিখিতটি নিয়ে এসেছি, যা আমার ক্ষেত্রে দুর্দান্ত কাজ করে:

- (double)tableView:(NSTableView *)tableView heightOfRow:(long)row
{
    if (tableView == self.tableViewTodo)
    {
        CKRecord *record = [self.arrayTodoItemsFiltered objectAtIndex:row];
        NSString *text = record[@"title"];

        double someWidth = self.tableViewTodo.frame.size.width;
        NSFont *font = [NSFont fontWithName:@"Palatino-Roman" size:13.0];
        NSDictionary *attrsDictionary =
        [NSDictionary dictionaryWithObject:font
                                    forKey:NSFontAttributeName];
        NSAttributedString *attrString =
        [[NSAttributedString alloc] initWithString:text
                                        attributes:attrsDictionary];

        NSRect frame = NSMakeRect(0, 0, someWidth, MAXFLOAT);
        NSTextView *tv = [[NSTextView alloc] initWithFrame:frame];
        [[tv textStorage] setAttributedString:attrString];
        [tv setHorizontallyResizable:NO];
        [tv sizeToFit];

        double height = tv.frame.size.height + 20;

        return height;
    }

    else
    {
        return 18;
    }
}

আমার ক্ষেত্রে আমি একটি প্রদত্ত কলামটি উল্লম্বভাবে প্রসারিত করতে চেয়েছিলাম যাতে আমি সেই লেবেলে প্রদর্শিত পাঠ্যটি পুরোপুরি ফিট করে So
ক্লাজদ দেদা

3

যেহেতু আমি কাস্টম ব্যবহার করি NSTableCellViewএবং NSTextFieldআমার সমাধানটিতে আমার প্রবেশাধিকার ছিল কোনও পদ্ধতি যুক্ত করা NSTextField

@implementation NSTextField (IDDAppKit)

- (CGFloat)heightForWidth:(CGFloat)width {
    CGSize size = NSMakeSize(width, 0);
    NSFont*  font = self.font;
    NSDictionary*  attributesDictionary = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
    NSRect bounds = [self.stringValue boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:attributesDictionary];

    return bounds.size.height;
}

@end

ধন্যবাদ! আপনি আমার ত্রাণকর্তা! এটিই একমাত্র সঠিকভাবে কাজ করে। আমি এটি একটি পুরো দিন ব্যয়।
টমি


2

এটি ঠিক করার জন্য আমি যা করেছি তা এখানে:

উত্স: "সারি উচ্চতা এনস্টেবলভিউ" এর অধীনে এক্সকোড ডকুমেন্টেশন সন্ধান করুন। আপনি "টেবিলভিউ পরিবর্তনশীল রওহাইটস / টেবিলভিউ পরিবর্তনশীল রওহাইটস অ্যাপডিলিগেট.এম" নামে একটি নমুনা উত্স কোড পাবেন

(দ্রষ্টব্য: আমি সারণী দৃশ্যে 1 কলামটি দেখছি, অন্য কোথাও দেখার জন্য আপনাকে টুইঙ্ক করতে হবে)

প্রতিনিধি

IBOutlet NSTableView            *ideaTableView;

ডেলিগেট.এম

সারণী দৃশ্যের সারি উচ্চতার নিয়ন্ত্রণ প্রতিনিধি

    - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
    // Grab the fully prepared cell with our content filled in. Note that in IB the cell's Layout is set to Wraps.
    NSCell *cell = [ideaTableView preparedCellAtColumn:1 row:row];

    // See how tall it naturally would want to be if given a restricted with, but unbound height
    CGFloat theWidth = [[[ideaTableView tableColumns] objectAtIndex:1] width];
    NSRect constrainedBounds = NSMakeRect(0, 0, theWidth, CGFLOAT_MAX);
    NSSize naturalSize = [cell cellSizeForBounds:constrainedBounds];

    // compute and return row height
    CGFloat result;
    // Make sure we have a minimum height -- use the table's set height as the minimum.
    if (naturalSize.height > [ideaTableView rowHeight]) {
        result = naturalSize.height;
    } else {
        result = [ideaTableView rowHeight];
    }
    return result;
}

নতুন সারির উচ্চতা কার্যকর করার জন্য আপনার এটিরও প্রয়োজন (প্রতিনিধি পদ্ধতি)

- (void)controlTextDidEndEditing:(NSNotification *)aNotification
{
    [ideaTableView reloadData];
}

আশা করি এটা কাজে লাগবে.

চূড়ান্ত দ্রষ্টব্য: এটি কলামের প্রস্থ পরিবর্তন করে না।


4
দুর্ভাগ্যক্রমে যে অ্যাপল স্যাম্পল কোড (বর্তমানে সংস্করণ 1.1 হিসাবে চিহ্নিত করা হয়েছে) একটি সেল-ভিত্তিক টেবিল ব্যবহার করে, ভিউ-ভিত্তিক টেবিল নয় (যা এই প্রশ্নটি সম্পর্কে রয়েছে)। কোড কলগুলি -[NSTableView preparedCellAtColumn:row], যা দস্তাবেজগুলি বলেছে "কেবলমাত্র এনএসসেল-ভিত্তিক টেবিল দর্শনের জন্য উপলভ্য"। "দেখুন ভিত্তিক NSTableView ত্রুটি:: preparedCellAtColumn: সারি: বলা হয় পদ্ধতি ব্যবহার করে এই লগ থেকে ব্যাক-ট্রেস, অথবা স্টপ সাথে একটি বাগ লগ ইন করুন।" একটি দৃশ্য ভিত্তিক টেবিলের উপর এই পদ্ধতি ব্যবহার করে রান সময়ে এই লগ আউটপুট উৎপন্ন হয়।
অ্যাশলে

1

এখানে জনএপোথেকারের উত্তরের ভিত্তিতে একটি সমাধান দেওয়া হয়েছে, যা cellView.fittingSize.heightআমার জন্য সঠিক উচ্চতা ফিরিয়ে দিচ্ছে না হিসাবে পরিবর্তিত হয়েছে । আমার ক্ষেত্রে আমি স্ট্যান্ডার্ড NSTableCellView, NSAttributedStringঘরের টেক্সটফিল্ড পাঠ্যের জন্য এবং আইবিতে সেট করা সেলটির পাঠ্য ফিল্ডের প্রতিবন্ধকতা সহ একটি একক কলামের টেবিল ব্যবহার করছি।

আমার দর্শন নিয়ামকটিতে, আমি ঘোষণা করি:

var tableViewCellForSizing: NSTableCellView?

ভিডডিডোডে ():

tableViewCellForSizing = tableView.make(withIdentifier: "My Identifier", owner: self) as? NSTableCellView

শেষ পর্যন্ত, টেবিলভিউ প্রতিনিধি পদ্ধতির জন্য:

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    guard let tableCellView = tableViewCellForSizing else { return minimumCellHeight }

    tableCellView.textField?.attributedStringValue = attributedString[row]
    if let height = tableCellView.textField?.fittingSize.height, height > 0 {
        return height
    }

    return minimumCellHeight
}

mimimumCellHeightব্যাকআপের জন্য 30 এ ধ্রুবক সেট, তবে বাস্তবে কখনও ব্যবহৃত হয় না। attributedStringsআমার মডেল অ্যারে NSAttributedString

এটি আমার প্রয়োজনের জন্য পুরোপুরি কাজ করে। পূর্ববর্তী সমস্ত উত্তরের জন্য ধন্যবাদ, যা আমাকে এই সমস্যাযুক্ত সমস্যার জন্য সঠিক দিক নির্দেশ করেছে।


4
খুব ভালো. একটি ইস্যু। সারণি সম্পাদনাযোগ্য বা টেক্সটফিল্ড হতে পারে না fitফিটসাইজ.হাইটটি কাজ করবে না এবং শূন্যে ফিরে আসবে। সেট টেবিল.এইডেবল = ভিডিডলোডে মিথ্যা
জিমিনিবব৯৯

0

এটি অনেকটা এমন কিছু শোনায় যা আগে আমার করতে হয়েছিল। আমি আশা করি আমি আপনাকে বলতে পারি যে আমি একটি সহজ, মার্জিত সমাধান নিয়ে এসেছি তবে হায়, আমি তা করি নি। চেষ্টা করার অভাবের জন্য নয়। যেমন আপনি ইতিমধ্যে ইউটিআইটিভিউয়ের প্রয়োজনীয়তাগুলি লক্ষ্য করেছেন যে কক্ষগুলি তৈরি হওয়ার পূর্বে উচ্চতাটি জানার জন্য এটি সমস্তই বৃত্তাকার বলে মনে হয়।

আমার সর্বোত্তম সমাধানটি ছিল যুক্তিটিকে ঘরের দিকে ঠেলে দেওয়া, কারণ কোষগুলি কীভাবে বিছানো হয়েছিল তা বুঝতে কম্বলটি কী প্রয়োজন তা আমি কমপক্ষে বিচ্ছিন্ন করতে পারি। মত একটি পদ্ধতি

+ (CGFloat) heightForStory:(Story*) story

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

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