ios - आईओएस 8 UITableView विभाजक इन्सेट 0 काम नहीं कर रहा है




objective-c swift (20)

स्विफ्ट 2.0 एक्सटेंशन

मैं बस टेबलव्यू सेल सेपरेटर्स से मार्जिन को हटाने के लिए किए गए एक एक्सटेंशन को साझा करना चाहता था।

extension UITableViewCell {
    func removeMargins() {

        if self.respondsToSelector("setSeparatorInset:") {
            self.separatorInset = UIEdgeInsetsZero
        }

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

        if self.respondsToSelector("setLayoutMargins:") {
            self.layoutMargins = UIEdgeInsetsZero
        }
    }
}

संदर्भ में प्रयुक्त:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell

मेरे पास एक ऐप है जहां UITableView का विभाजक इन्सेट कस्टम मानों पर सेट है - दाएं 0 , बाएं 0 । यह iOS 7.x में पूरी तरह से काम करता है, हालांकि iOS 8.0 मैं देखता हूं कि विभाजक इन्सेट दाईं ओर 15 के डिफ़ॉल्ट पर सेट है। भले ही xib फ़ाइलों में यह 0 सेट हो, फिर भी यह गलत तरीके से दिखाई देता है।

मैं UITableViewCell विभाजक मार्जिन को कैसे हटा सकता हूं?


बहुत जांच के बाद ...

इस सामान को पूरी तरह से नियंत्रित करने का एकमात्र तरीका यहां है (जो मुझे मिल सकता है)

प्रत्येक सेल पर विभाजक इन्सेट और लेआउट मार्जिन दोनों को पूरी तरह से नियंत्रित करने के लिए। अपने UITableviewDelegate पर willDisplayCell विधि में ऐसा करें।

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.layoutMargins = UIEdgeInsetsZero
    cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
    cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

सेल ऑब्जेक्ट विभाजक को नियंत्रित करता है, और सामग्री contentView नियंत्रित करता है। यदि आपके विभाजक इन्सेट स्पेस एक अप्रत्याशित रंग में दिखाई दे रहे हैं तो इसे हल करना चाहिए:

cell.backgroundColor = cell.contentView.backgroundColor

अधिकांश उत्तर अलग-अलग विधियों (यानी, viewDidLayoutSubviews , willDisplayCell , आदि) पर सेल और willDisplayCell लिए सेट किए जा रहे विभाजक इन्सेट और लेआउट मार्जिन दिखा रहे हैं, लेकिन मुझे पता चला है कि इन्हें केवल willDisplayCell में डालना बहुत अच्छा काम करता है। सबसे साफ तरीके की तरह लगता है।

// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    [cell setSeparatorInset:UIEdgeInsetsZero];

आइए इसे ठीक करने के प्रयास में अंधेरे से चार्ज करने से पहले समस्या को समझने के लिए एक पल लें।

डीबगर में एक त्वरित पोक आपको बताएगा कि विभाजक लाइनें UITableViewCell के UITableViewCell । ऐसा लगता है कि सेल इन लाइनों के लेआउट के लिए उचित जिम्मेदारी लेता है।

आईओएस 8 लेआउट मार्जिन की अवधारणा पेश करता है। डिफ़ॉल्ट रूप से, दृश्य के लेआउट मार्जिन सभी तरफ 8pt होते हैं, और वे पूर्वजों के विचारों से विरासत में प्राप्त होते हैं।

सबसे अच्छा हम बता सकते हैं कि, अपनी विभाजक रेखा को बाहर निकालने पर, UITableViewCell बाएं हाथ के लेआउट मार्जिन का सम्मान करने के लिए चुनता है, इसका उपयोग बाएं इंसेट को बाधित करने के लिए करता है।

वास्तव में शून्य की वांछित इन्सेट प्राप्त करने के लिए, सभी को एक साथ रखना, हमें यह करना होगा:

  • बाएं लेआउट मार्जिन को 0 सेट करें
  • किसी भी विरासत मार्जिन को ओवरराइड करना बंद करो

इस तरह रखो, यह हासिल करने के लिए एक बहुत ही आसान काम है:

cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;

ध्यान देने योग्य बातें:

  • यह कोड केवल प्रति सेल एक बार चलाने की आवश्यकता है (आप केवल सेल के गुणों को कॉन्फ़िगर कर रहे हैं), और जब आप इसे निष्पादित करना चुनते हैं तो इसके बारे में कुछ खास नहीं है। जो आपको सबसे साफ लगता है वह करो।
  • अफसोस की बात है कि इंटरफेस बिल्डर में कॉन्फ़िगर करने के लिए न तो संपत्ति उपलब्ध है, लेकिन यदि आप वांछित हैं तो आप preservesSuperviewLayoutMargins SuperviewLayoutMargins के लिए उपयोगकर्ता द्वारा परिभाषित रनटाइम विशेषता निर्दिष्ट कर सकते हैं।
  • जाहिर है, यदि आपका ऐप पहले ओएस रिलीज़ करता है, तो आपको आईओएस 8 और उसके बाद तक चलने तक उपरोक्त कोड को निष्पादित करने से बचने की आवश्यकता होगी।
  • PreservesSuperviewLayoutMargins को सेट करने के बजाय, आप पूर्व बाएं मार्जिन preservesSuperviewLayoutMargins पूर्वजों के विचार (जैसे तालिका) को कॉन्फ़िगर कर सकते हैं, लेकिन यह मूल रूप से अधिक त्रुटि-प्रवण प्रतीत होता है क्योंकि आप उस पूरे पदानुक्रम को नियंत्रित नहीं करते हैं।
  • यह शायद बाएं हाशिए को 0 पर सेट करने के लिए थोड़ा साफ होगा और दूसरों को छोड़ देगा।
  • यदि आप "अतिरिक्त" विभाजक पर 0 इन्सेट चाहते हैं कि UITableView सादा शैली तालिकाओं के नीचे खींचता है, तो मुझे लगता है कि तालिका स्तर पर भी वही सेटिंग्स निर्दिष्ट करने की आवश्यकता होगी (इसने कोशिश नहीं की है!)

आईओएस 8 में:

इसे मेरे UITableViewCell Subclass में जोड़ना:

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

और यह "tableView: cellForRowAtIndexPath" या "tableView: willDisplayCell" पर:

[editCell setSeparatorInset:UIEdgeInsetsZero];

मेरे लिए काम किया


आईओएस 9 के लिए आपको जोड़ने की जरूरत है:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

अधिक जानकारी के लिए कृपया question देखें।


आर्ग !!! अपने Cell सबक्लास में ऐसा करने के बाद या तो खेलने के बाद:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

या cell.layoutMargins = UIEdgeInsetsZero; सेट करना cell.layoutMargins = UIEdgeInsetsZero; यह मेरे लिए तय किया।


एक कस्टम UITableViewCell साथ आईओएस 8 के लिए स्विफ्ट में सरल समाधान

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

इस तरह आप layoutMargin और separatorInset सेट कर रहे हैं, प्रत्येक willDisplayCell लिए इसे करने के बजाए सिर्फ एक बार willDisplayCell क्योंकि उपर्युक्त उत्तरों में से अधिकांश सुझाव देते हैं।

यदि आप कस्टम UITableViewCell का उपयोग कर रहे हैं तो यह करने के लिए यह सही जगह है। अन्यथा आपको इसे tableView:cellForRowAtIndexPath में करना चाहिए tableView:cellForRowAtIndexPath

बस एक और संकेत: आपको preservesSuperviewLayoutMargins = false सेट करने की आवश्यकता नहीं है क्योंकि डिफ़ॉल्ट मान पहले से ही NO !


फर्श 3 पर उत्तरों को देखने के बाद, मैंने यह पता लगाने की कोशिश की कि टेबलव्यू और टेबल व्यूसेल के बीच विभाजक को सेट करने का क्या संबंध है और कुछ परीक्षण किया। यहां मेरे निष्कर्ष हैं:

  1. हम इस बात पर विचार कर सकते हैं कि सेल के विभाजक को शून्य पर सेट करने के लिए विभाजक को दो चरणों में स्थानांतरित करना है: पहला चरण सेल के विभाजक को शून्य पर सेट करना है। दूसरा चरण सेल के मार्जिनलेआउट को शून्य पर सेट करना है।

  2. TableView के विभाजक सेटसेट को सेट करें और मार्जिनलेआउट सेल के विभाजक को प्रभावित कर सकता है। हालांकि, परीक्षण से, मुझे लगता है कि टेबल व्यू का सेपरेटरिनेट बेकार प्रतीत होता है, टेबल व्यू का मार्जिनलेआउट वास्तव में सेल के मार्जिनलेआउट को प्रभावित कर सकता है।

  3. सेल के PreservesSuperviewLayoutMargins = झूठी सेट, सेल पर TableView के मार्जिनलेआउट प्रभाव काट सकते हैं।

  4. समाधानों में से एक:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }
    

बस नीचे कोड जोड़ें इस कार्यक्रम को हल कर सकते हैं।

आप सौभाग्यशाली हों!

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

       if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
       }

       if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
           [cell setLayoutMargins:UIEdgeInsetsZero];
       }

}

मेरे लिए सरल लाइन ने काम किया

cell.layoutMargins = UIEdgeInsetsZero

मैंने इसे ऐसा करके काम किया:

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;

वैश्विक स्तर पर इन्सेट को हटाने का एक आसान तरीका यहां दिया गया है।

UITableViewCell+Extensions.swift :

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

AppDelegate application:didFinishLaunchingWithOptions: ::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

आप ए के बारे में सोच सकते हैं) एक्सटेंशन में separatorInset layoutMargins ओवरराइड करें, या बी) इसके बजाय layoutMargins लिए उपस्थिति प्रॉक्सी सेट करें। न तो काम करेगा। भले ही separatorInset इंसेट को एक संपत्ति के रूप में इंगित किया गया हो, फिर भी इसे संपत्ति (या विधि) के रूप में ओवरराइड करने का प्रयास कंपाइलर त्रुटियों को उत्पन्न करता है। और UITableViewCell के layoutMargins लिए उपस्थिति प्रॉक्सी सेट करना layoutMargins (या, उस मामले के लिए, UITableView के layoutMargins और separatorInset layoutMargins लिए उपस्थिति प्रॉक्सी को भी सेट करना) का कोई प्रभाव नहीं पड़ता है।


सबसे अधिक वोट किए गए उत्तर से अधिक कॉम्पैक्ट तरीके में ...

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

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}


स्विफ्ट में यह थोड़ा अधिक परेशान है क्योंकि layoutMargins एक संपत्ति है, इसलिए आपको गेटर और सेटर को ओवरराइड करना होगा।

override var layoutMargins: UIEdgeInsets {
  get { return UIEdgeInsetsZero }
  set(newVal) {}
}

यह प्रभावी ढंग से layoutMargins को layoutMargins , जो मेरे मामले में ठीक है।


स्विफ्ट में लुकाज़ जवाब:

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }

layoutMargins और layoutMargins को अद्यतन करने के बजाय हर बार जब सेल स्क्रॉल करता है ( willDisplayCell का उपयोग willDisplayCell ), मैं willDisplayCell इसे एक बार करने का सुझाव willDisplayCell :

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

आईओएस 8.0 कक्ष और तालिका दृश्यों पर लेआउट मार्जिन संपत्ति लेआउट पेश करता है।

यह संपत्ति आईओएस 7.0 पर उपलब्ध नहीं है, इसलिए आपको यह सुनिश्चित करने की ज़रूरत है कि आप इसे निर्दिष्ट करने से पहले जांच लें!

इसके अतिरिक्त, ऐप्पल ने आपके सेल में एक संपत्ति जोड़ा है जो इसे आपके टेबल व्यू की मार्जिन सेटिंग्स को विरासत में रखने से रोक देगा। जब यह प्रॉपर्टी सेट की जाती है, तो आपकी कोशिकाओं को तालिका दृश्य के स्वतंत्र रूप से अपने मार्जिन को कॉन्फ़िगर करने की अनुमति होती है। इसे ओवरराइड के रूप में सोचें।

इस संपत्ति को preservesSuperviewLayoutMargins जाता है layoutMargin , और इसे NO सेट करने से सेल के layoutMargin की अनुमति मिल जाएगी layoutMargin सेटिंग जो भी layoutMargin ओवरराइड करने के लिए आपके layoutMargin पर सेट है। यह दोनों समय बचाता है ( आपको तालिका दृश्य की सेटिंग्स को संशोधित करने की आवश्यकता नहीं है ), और अधिक संक्षेप में है। कृपया एक विस्तृत स्पष्टीकरण के लिए माइक अब्दुल्ला के जवाब का संदर्भ लें।

नोट: माइक अब्दुल्ला के जवाब में व्यक्त किए गए अनुसार सेल-स्तरीय मार्जिन सेटिंग के लिए एक साफ कार्यान्वयन निम्नानुसार है। अपने सेल के संरक्षक को सेट करना SuperviewLayoutMargins = NO यह सुनिश्चित करेगा कि आपका टेबल व्यू सेल सेटिंग्स को ओवरराइड नहीं करता है। यदि आप वास्तव में अपने पूरे टेबल दृश्य को लगातार मार्जिन चाहते हैं, तो कृपया तदनुसार अपना कोड समायोजित करें।

अपने सेल मार्जिन सेटअप करें:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

अपने सेल पर preservesSuperviewLayoutMargins प्रॉपर्टी को सेट करने से आपके सेल मार्जिन को ओवरराइड करने से आपके टेबल व्यू को रोकना चाहिए । कुछ मामलों में, ऐसा लगता है कि यह ठीक से काम नहीं करता है।

यदि सभी विफल हो जाते हैं, तो आप अपने टेबल व्यू मार्जिन को क्रूर-बल कर सकते हैं:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
} 

... और तुम वहाँ जाओ! यह आईओएस 7 और 8 पर काम करना चाहिए।

संपादित करें: मोहम्मद सालेह ने आईओएस 9 में एक संभावित बदलाव पर ध्यान दिया। यदि आप cellLayoutMarginsFollowReadableWidth या मार्जिन को कस्टमाइज़ करना चाहते हैं तो आपको टेबल व्यू के cellLayoutMarginsFollowReadableWidth करने cellLayoutMarginsFollowReadableWidth को सेट करने की आवश्यकता हो सकती है। आपका लाभ भिन्न हो सकता है, यह बहुत अच्छी तरह से प्रलेखित नहीं है।

यह संपत्ति केवल आईओएस 9 में मौजूद है इसलिए सेटिंग से पहले जांचना सुनिश्चित करें।

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

( आईओएस 8 से कोड के ऊपर UITableView विभाजक इन्सेट 0 काम नहीं कर रहा है )

संपादित करें: यहां एक शुद्ध इंटरफ़ेस बिल्डर दृष्टिकोण है:

नोट: आईओएस 11 इस व्यवहार में से अधिकांश को बदलता है और सरल बनाता है, एक अपडेट आगामी होगा ...


इस स्निपेट को जोड़ना, आईओएस 8 में स्विफ्ट में सरल सुरुचिपूर्ण काम करता है :)

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}

यह आईओएस 8 और आईओएस 9 में मेरे लिए पूरी तरह से काम किया।

के लिए Obj सी

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  { 
        if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
        {
            [tableView setSeparatorInset:UIEdgeInsetsZero];
        }

        if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
        {
            [tableView setLayoutMargins:UIEdgeInsetsZero];
        }

        if ([cell respondsToSelector:@selector(setLayoutMargins:)])
        {
            [cell setLayoutMargins:UIEdgeInsetsZero];
        }
         return cell;
    }




ios8