it-swarm.asia

UITableview: كيفية تعطيل التحديد للصفوف ولكن ليس للآخرين

أنا أعرض في مجموعة tableview محتويات موزعة من XML. أريد تعطيل حدث النقر عليه (لا ينبغي أن أتمكن من النقر فوقه على الإطلاق) يحتوي الجدول على مجموعتين. أريد تعطيل التحديد للمجموعة الأولى فقط ولكن ليس للمجموعة الثانية. النقر فوق الصف الأول من المجموعة الثانية navigates إلى أنبوبي player view.

كيف يمكنني تحديد مجموعات أو صفوف محددة فقط؟

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if(indexPath.section!=0)
    if(indexPath.row==0)    

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];   
}

شكر.

272
Warrior

عليك فقط وضع هذا الكود في cellForRowAtIndexPath

لتعطيل خاصية تحديد الخلية: (أثناء النقر فوق الخلية)

cell.selectionStyle = UITableViewCellSelectionStyleNone;

لتمكين القدرة على تحديد (اضغط) الخلية: (النقر على الخلية)

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

لاحظ أن الخلية ذات selectionStyle = UITableViewCellSelectionStyleNone; ستظل تتسبب في استدعاء واجهة المستخدم didSelectRowAtIndexPath عند لمسها من قبل المستخدم. لتجنب ذلك ، قم بما هو مقترح أدناه وتعيين.

cell.userInteractionEnabled = NO;

في حين أن. لاحظ أيضًا أنك قد ترغب في تعيين cell.textLabel.enabled = NO; على اللون الرمادي للعنصر.

469
Pugal

إذا كنت تريد إنشاء صف (أو مجموعة فرعية من الصفوف) غير قابلة للاختيار ، فقم بتطبيق طريقة UITableViewDelegate-tableView:willSelectRowAtIndexPath: (كما ذكرها TechZen). إذا كان indexPath يجب ألا يكون قابل للتحديد ، ارجعnil، وإلا فأرجع indexPath. للحصول على سلوك التحديد الافتراضي ، يمكنك فقط إرجاع indexPath الذي تم تمريره إلى طريقة delegate ، ولكن يمكنك أيضًا تغيير تحديد الصف عن طريق إرجاع indexPath مختلفًا.

مثال:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // rows in section 0 should not be selectable
    if ( indexPath.section == 0 ) return nil;

    // first 3 rows in any section should not be selectable
    if ( indexPath.row <= 2 ) return nil;

    // By default, allow row to be selected
    return indexPath;
}
336
Brian Chapados

بدءًا من iOS 6 ، يمكنك استخدام

-tableView:shouldHighLightRowAtIndexPath:

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

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

مرجع بروتوكول UITableViewDelegate

53
Keller

لا شيء من الإجابات أعلاه يعالج المشكلة بشكل صحيح. السبب هو أننا نريد تعطيل اختيار الخلية ولكن ليس بالضرورة من المقاطع الفرعية داخل الخلية.

في حالتي كنت أعرض UISwitch في منتصف الصف وأردت تعطيل التحديد لبقية الصف (وهو فارغ) ولكن ليس للمفتاح! الطريقة الصحيحة للقيام بذلك هي بالتالي في الطريقة

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

حيث بيان النموذج

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

الطريقة التي تعد الخلية ولا تسمح بالتفاعل مع UISwitch.

علاوة على ذلك ، باستخدام الطريقة

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

من أجل إلغاء تحديد الخلية مع بيان النموذج

[tableView deselectRowAtIndexPath:indexPath animated:NO];

لا يزال يعرض الصف الذي يتم تحديده أثناء قيام المستخدم بالضغط على المحتوى الأصليعرض الخلية.

جمعية البناء الخيرية. أنا متأكد من أن الكثير سيجد هذا مفيدًا.

16
MightyMouse

يمكنك تعويض التحديدات باستخدام طرق مصدر البيانات هذه.

– tableView:willSelectRowAtIndexPath: 
– tableView:didSelectRowAtIndexPath: 
– tableView:willDeselectRowAtIndexPath: 
– tableView:didDeselectRowAtIndexPath:

في هذه الطرق ، تتحقق مما إذا كان الصف المحدد هو الصف الذي تريد تحديده أم لا. إذا كان الأمر كذلك ، اتخذ إجراءً ، إن لم يكن ، لا تفعل شيئًا.

لسوء الحظ ، لا يمكنك إيقاف التحديد لقسم واحد فقط. إنها الطاولة بأكملها أو لا شيء.

ومع ذلك يمكنك تعيين خلايا الجدول selectionStyle property إلى UITableViewCellSelectionStyleNone. أعتقد أن ذلك سيجعل الاختيار غير مرئي. مع الأساليب المذكورة أعلاه التي يجب أن تجعل الخلايا تبدو خاملة تماما من وجهة نظر المستخدم.

Edit01:

إذا كان لديك جدول يمكن فيه تحديد بعض الصفوف فقط ، فمن المهم أن تكون خلايا الصفوف القابلة للتحديد متميزة بصريًا عن الصفوف غير القابلة للاختيار. زر ملحق شيفرون هو الطريقة الافتراضية للقيام بذلك.

ومع ذلك ، فأنت لا تريد أن يحاول المستخدمون تحديد الصفوف والتفكير في أن التطبيق قد تعطل لأن الصف لا يفعل أي شيء.

10
TechZen

لـ Swift 4.0 على سبيل المثال:

cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5
9
Alessandro Ornano

تحتاج إلى القيام بشيء مثل التالي لتعطيل تحديد الخلية ضمن طريقة cellForRowAtIndexPath:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];

لإظهار الخلية باللون الرمادي ، ضع ما يلي ضمن طريقة tableView:WillDisplayCell:forRowAtIndexPath:

[cell setAlpha:0.5];

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

9
azfar

حل بلدي على أساس نموذج البيانات:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled ? indexPath : nil
}

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled
}
5
SoftDesigner

لإيقاف استخدام بعض الخلايا فقط:

cell.userInteractionEnabled = NO;

بالإضافة إلى منع التحديد ، يؤدي هذا أيضًا إلى إيقاف tableView: didSelectRowAtIndexPath: يتم استدعاء الخلايا التي تحتوي عليها.

5
JosephH

يمكنك استخدام الأسلوب tableView:willDisplayCell للقيام بجميع أنواع التخصيص إلى tableViewCell.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
     [cell setUserInteractionEnabled:NO];

     if (indexPath.section == 1 && indexPath.row == 0)
     {
         [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
         [cell setUserInteractionEnabled:YES];
     }
} 

في هذا الرمز أعلاه ، يمكن للمستخدم فقط تحديد الصف الأول في القسم الثاني من الجدول. لا يمكن تحديد بقية الصفوف. شكرا! ~

4
Abdul Rahman

لـ Swift 4.0 هذا سيفعل الخدعة. سيتم تعطيل "الخلية" في طريقة didSelectRowAtIndexPath ولكن مع بقاء المقابلات الفرعية قابلة للنقر.

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
         if (indexPath.row == clickableIndex ) { 
            return indexPath
         }else{
            return nil
        }
    }
4
Nilesh

لـ Swift:

cell.selectionStyle = .None
cell.userInteractionEnabled = false
3
Esqarrouth

بسيط

ما عليك سوى استخدام cell.userInteractionEnabled = YES; في الخلية إذا كان يمكنها التنقل و cell.userInteractionEnabled = NO; على خلاف ذلك

1
Rick Royd Aban

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

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
        return nil;
    }
    return indexPath;
}
1
Jeffery Jones

استخدم هذا لجعل الخلية تبدو وكأنها تم تعطيلها وغير قابلة للاختيار:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

هام: لاحظ أن هذه خاصية تصميم فقط ولا تؤدي إلى تعطيل الخلية بالفعل. للقيام بذلك ، يجب عليك التحقق من selectionStylein didSelectRowAtIndexPath: الخاص بتنفيذ المفوض:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
        return;
    }

    // do your cell selection handling here
}
1
pt2ph8

أنا أحب براين Chapados الإجابة أعلاه. ومع ذلك ، هذا يعني أنه قد يكون لديك منطق مكرر في كل من cellForRowAtIndexPath ومن ثم في willSelectRowAtIndexPath والذي يمكن أن ينقطع بسهولة عن المزامنة. بدلاً من تكرار المنطق ، فقط تحقق من selectStyle:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
        return nil;

    else
        return indexPath;
}
1
Eric D'Souza

على Xcode 7 بدون تشفير يمكنك ببساطة القيام بما يلي:

في عرض المخطط التفصيلي ، حدد خلية عرض الجدول. (الخلية متداخلة ضمن مشهد وحدة تحكم عرض الجدول> وحدة تحكم عرض الجدول> عرض الجدول. قد تضطر إلى الكشف عن هذه الكائنات لرؤية خلية عرض الجدول)

في عارض الخصائص ، ابحث عن الحقل المسمى Selection وحدد None. atribute inspector مع هذا الخيار ، لن تحصل الخلية على تمييز مرئي عند قيام المستخدم بالنقر فوقها.

1
Tung Fam

قم بتنفيذ الطريقة tableView:willSelectRowAtIndexPath: فقط في مصدر البيانات لجدولك. إذا كنت تريد تمييز الصف في المسار ، فقم بإرجاع indexPath المحدد. إذا لم تقم بذلك ، فارجع إلى الصفر.

مثال من تطبيقي:

- (NSIndexPath *)tableView:(UITableView *)tableView
    willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MySelectableObj* obj = [self objectAtPath:indexPath];
    if(obj==nil) return nil;
    return indexPath;
}

الشيء الجميل في هذا الأمر هو أنه لن يتم استدعاء shouldPerformSegueWithIdentifier:sender: في حالة إرجاع الطريقة أعلاه إلى الصفر ، على الرغم من أنني كررت الاختبار أعلاه فقط من أجل الاكتمال.

0
user3821934

بالنسبة إلى Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;
0
uplearnedu.com

وأنا أتفق مع إجابة براين

إذا فعلت

cell.isUserInteractionEnabled = false 

ثم لن يتم تفاعل المستخدم مع المقابلات الفرعية داخل الخلية.

على الموقع الآخر ، الإعداد

cell.selectionStyle = .none

سيتم تشغيل طريقة didSelect على الرغم من عدم تحديث لون التحديد.

باستخدام willSelectRowAt هو الطريقة التي حل بها مشكلتي. مثال:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {

    if indexPath.section == 0{

        if indexPath.row == 0{
            return nil
        }

    }
    else if indexPath.section == 1{

        if indexPath.row == 0{
            return nil
        }

    }

    return indexPath

}
0
Reimond Hill