سؤال

أريد إخفاء/إظهار بعض الأعمدة ديناميكيًا في NSTableView، بناءً على البيانات التي سيتم عرضها - بشكل أساسي، إذا كان العمود فارغًا، فأنا أرغب في إخفاء العمود.أقوم حاليًا بملء الجدول بفئة وحدة التحكم كمفوض للجدول.

أيه أفكار؟أرى أنه يمكنني تعيين العمود المخفي في Interface Builder، ولكن لا يبدو أن هناك وقتًا مناسبًا لتصفح الأعمدة والتحقق مما إذا كانت فارغة أم لا، حيث لا يبدو أن هناك طريقة يتم استدعاؤه قبل/بعد ملء كافة البيانات الموجودة في الجدول.

هل كانت مفيدة؟

المحلول

NSTable هو مجرد الفصل الذي يرسم الجدول.كما قلت بنفسك، لديك فئة معينة تعطيها الجدول كمفوض وتقوم هذه الفئة بتغذية الجدول بالبيانات المراد عرضها.إذا قمت بتخزين بيانات الجدول كبيانات NSArray ضمن فئة المفوض الخاص بك، فسيكون من السهل معرفة ما إذا كان أحد الأعمدة فارغًا، أليس كذلك؟ويسأل NSArray فصلك عبر طريقة المفوض عن عدد الأعمدة الموجودة، لذلك عندما يُطلب منك ذلك، لماذا لا تبحث عن عدد الأعمدة التي تحتوي على بيانات والإبلاغ عن هذا الرقم بدلاً من العدد الحقيقي للأعمدة التي تخزنها داخليًا ثم عندما يُطلب منك ذلك توفير بيانات (العمود، الصف)، فقط تخطي العمود الفارغ.

نصائح أخرى

في نظام التشغيل Mac OS X v10.5 والإصدارات الأحدث، يوجد setHidden: محدد لـ NSTableColumn.

يتيح ذلك إخفاء/إظهار الأعمدة ديناميكيًا باستخدام المعرفات:

NSInteger colIdx;
NSTableColumn* col;

colIdx = [myTable columnWithIdentifier:@"columnIdent"];
col = [myTable.tableColumns objectAtIndex:colIdx];
[col setHidden:YES];

لقد فعلت ذلك مع الارتباطات، لكن قمت بإعدادها برمجيًا بدلاً من إعدادها من خلال Interface Builder.

يجب أن يمنحك هذا المقتطف الزائف جوهره:

NSTableColumn *aColumn = [[NSTableColumn alloc] initWithIdentifier:attr];
[aColumn setWidth:DEFAULTCOLWIDTH];
[aColumn setMinWidth:MINCOLWIDTH];
[[aColumn headerCell] setStringValue:columnLabel];

[aColumn bind:@"value"
     toObject:arrayController 
  withKeyPath:keyPath 
  options:nil];             

[tableView addTableColumn:aColumn];
[aColumn release];

بالطبع يمكنك إضافة التنسيقات وكل تلك الأشياء أيضًا.

لا يعمل في Interface Builder.ومع ذلك فهو يعمل برمجيا.إليك كيفية ربط NSTableViewColumn بمعرف "الحالة" بمفتاح في NSUserDefaults الخاص بي:

سويفت:

tableView.tableColumnWithIdentifier("Status")?.bind("hidden", toObject: NSUserDefaults.standardUserDefaults(), withKeyPath: "TableColumnStatus", options: nil)

ج موضوعية:

[[self.tableView tableColumnWithIdentifier:@"Status"] bind:@"hidden" toObject:[NSUserDefaults standardUserDefaults] withKeyPath:@"TableColumnStatus" options:nil];

ليس لدي إجابة كاملة في هذا الوقت، ولكن انظر إلى Bindings.من الممكن عمومًا القيام بكل أنواع الأشياء باستخدام Cocoa Bindings.

لا يوجد ربط رؤية لـ NSTableColumn، ولكن قد تتمكن من ضبط العرض على 0.

ثم يمكنك ربطه بالعنصر النائب Null، وتعيين هذه القيمة على 0 - ولكن لا تنس تعيين العناصر النائبة الأخرى على قيم معقولة.

(كما قلت، هذه مجرد بداية، وقد تحتاج إلى بعض التغيير والتبديل).

لا يوجد وقت واحد يتم فيه ملء جميع البيانات.لا يقوم NSTableView بتخزين البيانات، بل يطلبها ديناميكيًا من مصدر البيانات الخاص به (أو الكائنات المرتبطة إذا كنت تستخدم الارتباطات).إنه يرسم فقط باستخدام البيانات التي يحصل عليها من مصدر البيانات ويتخلص منها.من المفترض ألا ترى الجدول يطلب بيانات لأي شيء غير مرئي، على سبيل المثال.

يبدو أنك تستخدم مصدر بيانات؟عندما تتغير البيانات، تقع على عاتقك مسؤولية استدعاء -reloadData على الجدول، وهي تسمية خاطئة إلى حد ما.إنه أشبه بـ "إبطال كل شيء".

وهذا يعني أنك يجب أن تعرف بالفعل متى تتغير البيانات.هذه هي النقطة التي يمكنك عندها حساب الأعمدة التي يجب إخفاؤها.

@amrox - إذا كنت أفهم اقتراحك بشكل صحيح، فأنت تقول أنه يجب علي ربط قيمة بالخاصية المخفية لـ NSTableColumns في الجدول الخاص بي؟يبدو أن هذا سينجح، ولكن لا أعتقد أن NSTableColumn له خاصية مخفية، نظرًا لأن رسائل isHidden وsetHidden تتحكم في رؤية العمود - مما يخبرني أن هذه ليست خاصية، إلا إذا فاتني شيء ما (وهو أمر ممكن تماما).

أرغب في نشر الحل المحدث لـ Swift 4 باستخدام روابط Cocoa والحل الفعلي isHidden العلم دون لمس عرض الأعمدة (حيث قد تحتاج إلى استعادة القيمة الأصلية بعد ذلك...).لنفترض أن لدينا مربع اختيار لتبديل رؤية بعض الأعمدة (أو يمكنك دائمًا تبديل الخيار hideColumnsFlag المتغير في المثال أدناه بأي طريقة أخرى تريدها):

class ViewController: NSViewController {

     // define the boolean binding variable to hide the columns and use its name as keypath
     @objc dynamic var hideColumnsFlag = true

     // Referring the column(s)
     // Method 1: creating IBOutlet(s) for the column(s): just ctrl-drag each column here to add it
     @IBOutlet weak var hideableTableColumn: NSTableColumn!
     // add as many column outlets as you need...

     // or, if you prefer working with columns' string keypaths
     // Method 2: use just the table view IBOutlet and its column identifiers (you **must** anyway set the latter identifiers manually via IB for each column)
     @IBOutlet weak var theTableView: NSTableView! // this line could be actually removed if using the first method on this example, but in a real case, you will probably need it anyway.

     // MARK: View Controller Lifecycle

     override func viewDidLoad() {
         super.viewDidLoad()

         // Method 1
         // referring the columns by using the outlets as such:
         hideableTableColumn.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column outlet.

         // Method 2
         // or if you need/prefer to use the column identifiers strings then:
         // theTableView.tableColumn(withIdentifier: .init("columnName"))?.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column identifier you have set.

         // obviously use just one method by commenting/uncommenting one or the other.
     }

     // MARK: Actions

     // this is the checkBox action method, just toggling the boolean variable bound to the columns in the viewDidLoad method.
     @IBAction func hideColumnsCheckboxAction(_ sender: NSButton) {
         hideColumnsFlag = sender.state == .on
     }
}

كما لاحظت، لا توجد طريقة حتى الآن لربط Hidden إشارة في Interface Builder كما في XCode10:يمكنك ان ترا ال Enabled أو Editable الارتباطات، ولكن برمجيًا فقط سيكون لديك حق الوصول إلى ملف isHidden علامة للعمود، كما يطلق عليه في سويفت.

كما هو مذكور في التعليقات، تعتمد الطريقة الثانية على معرفات الأعمدة التي يجب عليك تعيينها يدويًا إما عبر Interface Builder في حقل الهوية بعد تحديد الأعمدة ذات الصلة، أو إذا كان لديك مصفوفة من أسماء الأعمدة، فيمكنك تعداد أعمدة الجدول وتعيين المعرفات وكذلك الارتباطات بدلاً من تكرار أسطر التعليمات البرمجية المماثلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top