IOS11 में अजीब व्यवहारिक व्यवहार। सेल नेविगेशन पुश एनीमेशन के साथ स्क्रॉल करते हैं


116

मैंने हाल ही में कुछ कोड को नए iOS 11 बीटा 5 एसडीके में माइग्रेट किया है।

अब मुझे UITableView से एक बहुत ही भ्रमित व्यवहार मिलता है। टेबलव्यू ही नहीं है कि फैंसी। मेरे पास कस्टम सेल हैं लेकिन अधिकांश भाग में यह सिर्फ उनकी ऊंचाई के लिए है।

जब मैं टेबल व्यू के साथ अपने व्यू कंट्रोलर को धक्का देता हूं तो मुझे एक अतिरिक्त एनीमेशन मिलता है जहां सेल "स्क्रॉल अप" (या संभवत: पूरे टेबलव्यू फ्रेम को बदल दिया जाता है) और नीचे पुश / पॉप नेविगेशन एनीमेशन के साथ होता है। कृपया जिफ़ देखें:

लहराती टेबलव्यू

मैं मैन्युअल रूप tableviewसे loadViewविधि और सेटअप ऑटो लेआउट बाधाओं में अग्रणी, अनुगामी, शीर्ष, टेबलव्यू के पर्यवेक्षण के नीचे के बराबर होने के लिए बनाता हूं । सुपरवाइवे रूट कंट्रोलर ऑफ व्यू कंट्रोलर है।

कंट्रोलर पुश कोड बहुत मानक है: self.navigationController?.pushViewController(notifVC, animated: true)

समान कोड iOS 10 पर सामान्य व्यवहार प्रदान करता है।

क्या आप मुझे दिशा दे सकते हैं कि क्या गलत है?

EDIT: मैंने एक बहुत ही सरल टेबलव्यू कंट्रोलर बनाया है और मैं वहीं व्यवहार कर सकता हूं। कोड:

class VerySimpleTableViewController : UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        cell.textLabel?.text = String(indexPath.row)
        cell.accessoryType = .disclosureIndicator

        return cell
    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        let vc = VerySimpleTableViewController.init(style: .grouped)

        self.navigationController?.pushViewController(vc, animated: true)
    }
}

संपादित 2: मैं UINavigationBar के अपने अनुकूलन के लिए समस्या को कम करने में सक्षम था। मेरा इस तरह से एक अनुकूलन है:

rootNavController.navigationBar.setBackgroundImage(createFilledImage(withColor: .white, size: 1), for: .default)

जहां createFilledImageदिए गए आकार और रंग के साथ चौकोर छवि बनाता है।

अगर मैं इस लाइन पर टिप्पणी करता हूं तो मुझे सामान्य व्यवहार वापस मिल जाता है।

मैं इस मामले पर किसी भी विचार की सराहना करता हूं।


यह नौसेना बार के अनुकूलन के साथ एक मुद्दा नहीं हो सकता है। मैं बिना किसी अनुकूलन के एक ही मुद्दा (स्वीकृत उत्तर हल किया गया) कर रहा था। मुझे लगता है कि यह एक मुद्दा हो सकता है जिस तरह से आईओएस टेबलव्यू को हैंडल करता है जब इसे यूआईटेबल व्यू कॉन्ट्रोलर का उपयोग करने के बजाय मैन्युअल रूप से सबव्यू के रूप में बनाया जाता है।
मार्क लियोनार्ड

2
मैं इस व्यवहार को केवल जब मैं सेट दिखाई दे रही है navigationBar.isTranslucentकरने के लिए false, अन्यथा यह ठीक काम करता है।
b_ray

5
यह iOS11 GM में एक बग प्रतीत होता है, कृपया उस बग रिपोर्ट को दोहराएं ताकि इस समस्या पर Apple का कुछ ध्यान आए: Openradar.appspot.com/34465226
b_ray

1
यह मुद्दा iOS 11.2 बीटा में तय किया गया लगता है। मैं contentInsetAdjustmentBehavior को कभी सेट नहीं करूंगा क्योंकि यह स्क्रीन के नीचे पैडिंग नहीं देकर iPhone X स्क्रॉल साक्षात्कार को तोड़ देता है। आपके सामग्री दृश्य के नीचे iPhone X के होम "बटन" के नीचे रहता है।
Batu

जवाबों:


150

यह UIScrollView's (UITableView UIScrollview का एक उपवर्ग है) नई contentInsetAdjustmentBehaviorसंपत्ति के कारण है, जो .automaticडिफ़ॉल्ट रूप से सेट है ।

आप किसी भी प्रभावित नियंत्रकों के viewDidLoad में निम्नलिखित स्निपेट के साथ इस व्यवहार को ओवरराइड कर सकते हैं:

    tableView.contentInsetAdjustmentBehavior = .never

https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior


2
UIScrollViewContentInsetAdjustmentBehavior.automatic की परिभाषा पर यह टिप्पणी कहती है: "... पिछड़े संगतता के लिए भी ऊपर और नीचे की सामग्री को समायोजित करेगा। जब स्क्रॉल दृश्य स्वचालित रूप से AdAdsscrollViewInsets = YES के पास एक नेविगेशन नियंत्रक के अंदर दृश्य नियंत्रक के स्वामित्व में होता है, चाहे स्क्रॉल के बावजूद। दृश्य स्क्रॉल करने योग्य है ”। मेरा सिद्धांत है कि नेविगेशन बार की सामग्री इनसेट पृष्ठभूमि की छवि को स्थापित करने से प्रभावित होती है, जो तब गतिशील रूप से समायोजित होती है।
मैगी हिलन

8
आप स्टोरीबोर्ड के साथ भी ऐसा कर सकते हैं। आकार इंस्पेक्टर -> सामग्री इनसेट -> सेट 'कभी नहीं'।
वून्बी किम

4
यदि आपकी सामग्री टैब बार के पीछे फैली हुई है, tableView.contentInsetAdjustmentBehaviorतो इनसेट्स टूट जाएंगे।
कीन

4
इसके अलावा, बस इसे अक्षम करने से लैंडस्केप में iPhone X पर स्क्रॉल (ऊपर की ओर) पीछे संकेतक लग जाएगा। इस व्यवहार का पूरा बिंदु स्क्रॉल साक्षात्कार की सामग्री क्षेत्र को समायोजित करना है ताकि वे उन स्क्रीन पर दिखाई दें जो आयताकार नहीं हैं। मुझे लगता है कि हम केवल iPhone X Sim पर वर्तमान में इसे देख सकते हैं।
PhoneyDeveloper

8
यह समस्या iOS 11 में एक बग के कारण हुई थी, जहां दृश्य नियंत्रक के दृश्य के सुरक्षित नेविगेशन गलत तरीके से नेविगेशन संक्रमण के दौरान सेट किए गए थे, जिसे iOS 11.2 में तय किया जाना चाहिए। स्थापना contentInsetAdjustmentBehaviorकरने के लिए .neverएक महान वैकल्पिक हल क्योंकि यह संभावना अन्य अवांछनीय दुष्प्रभाव होगा नहीं है। यदि आप एक वर्कअराउंड का उपयोग करते हैं, तो आपको इसे iOS संस्करणों> = 11.2 के लिए निकालना सुनिश्चित करना चाहिए।
स्माइबॉर्ग

23

मैगी के जवाब के अलावा

उद्देश्य सी

if (@available(iOS 11.0, *)) {
    scrollViewForView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}

यह समस्या iOS 11 में एक बग के कारण हुई थी जहां safeAreaInsetsनेविगेशन नियंत्रक के दौरान व्यू कंट्रोलर का दृश्य गलत तरीके से सेट किया गया था, जिसे iOS 11.2 में ठीक किया जाना चाहिए। स्थापना contentInsetAdjustmentBehaviorकरने के लिए .neverएक महान वैकल्पिक हल क्योंकि यह संभावना अन्य अवांछनीय दुष्प्रभाव होगा नहीं है। यदि आप एक वर्कअराउंड का उपयोग करते हैं, तो आपको इसे iOS संस्करणों> = 11.2 के लिए निकालना सुनिश्चित करना चाहिए

स्माइबॉर्ग द्वारा अनुमोदित (Apple में सॉफ्टवेयर इंजीनियर)


6

उदाहरण के लिए NSProxy का उपयोग करके आप एक बार में इस व्यवहार को संपादित कर सकते हैं। FishishLaunchingWithOptions:

if (@available(iOS 11.0, *)) {
      [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} 

1
यह UIImagePickerController
galway

6

यहां बताया गया है कि कैसे मैं iOS 11 को स्वचालित रूप से सेट करने की अनुमति देते हुए इस समस्या को ठीक करने में कामयाब रहा । मैं उपयोग कर रहा हूं UITableViewController

  • स्टोरीबोर्ड (या प्रोग्रामेटिक रूप से ) में अपने व्यू कंट्रोलर में "किनारों को शीर्ष सलाखों के नीचे बढ़ाएं" और "अपारदर्शी बार के नीचे किनारों का विस्तार करें" चुनें । सुरक्षित क्षेत्र इनसेट आपके विचार को शीर्ष बार के नीचे जाने से रोकेंगे।
  • अपने स्टोरीबोर्ड में अपने टेबल व्यू पर "इनसेट्स टू सेफ एरिया" बटन की जांच करें। (या tableView.insetsContentViewsToSafeArea = true) - यह आवश्यक नहीं हो सकता है लेकिन यह वही है जो मैंने किया था।
  • सामग्री स्क्रॉल समायोजन व्यवहार को "स्क्रॉल करने योग्य अक्ष" (या tableView.contentInsetAdjustmentBehavior = .scrollableAxes) पर सेट करें - .alwaysयह भी काम कर सकता है लेकिन मैंने परीक्षण नहीं किया।

अन्य सभी विफल होने पर प्रयास करने के लिए एक और चीज:

viewSafeAreaInsetsDidChange UIViewControllerतालिका दृश्य प्राप्त करने के लिए ओवरराइड विधि को सुरक्षित क्षेत्र के इनसेट पर स्क्रॉल दृश्य इनसेट सेट करने के लिए बाध्य करें। यह मैगी के उत्तर में 'नेवर' सेटिंग के संयोजन में है।

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    self.tableView.contentInset = self.view.safeAreaInsets;
}

नोट: self.tableViewऔर के self.viewलिए एक ही बात होनी चाहिएUITableViewController


इस धागे पर लगभग सब कुछ करने की कोशिश की, और यह मेरे लिए काम किया। TabBarVC में एम्बेडेड TableViewVC। धन्यवाद!
जोश वोल्फ

3

यह इच्छित व्यवहार की तुलना में बग की तरह अधिक लगता है। यह तब होता है जब नेविगेशन बार पारभासी नहीं होता है या जब पृष्ठभूमि छवि सेट की जाती है।

यदि आप केवल सामग्री सेट करते हैं। InsetAdjustmentBehavior to .never, सामग्री insets को iPhone X पर सही ढंग से सेट नहीं किया जाएगा, उदाहरण के लिए स्क्रॉलबार के नीचे सामग्री नीचे के क्षेत्र में जाएगी।

यह दो काम करने के लिए आवश्यक है:
1.
स्क्रॉलव्यू को पुश / पॉप पर एनिमेट करने से रोकें । 2. सामान्य व्यवहार को बनाए रखें क्योंकि यह iPhone X के लिए आवश्यक है। इसके बिना चित्र में जैसे, सामग्री नीचे स्क्रॉलबार के नीचे जाएगी।

नया सरल समाधान: XIB में: अपने मुख्य दृश्य के शीर्ष पर नया UIView जोड़ें, पर्यवेक्षण और अग्रणी के लिए अनुगामी और ऊँचाई 0. पर सेट करें। आपको इसे अन्य साक्षात्कारों या किसी भी चीज़ से कनेक्ट करने की आवश्यकता नहीं है।

पुराना समाधान:

नोट: यदि आप लैंडस्केप मोड में UIScrollView का उपयोग कर रहे हैं, तो यह अभी भी क्षैतिज इनसेट्स (एक और बग) को सही ढंग से सेट नहीं करता है, इसलिए आपको IB में सेफएयरनेट्स के लिए स्क्रॉलव्यू के अग्रणी / अनुरेखण को पिन करना होगा।

नोट 2: नीचे दिए गए समाधान में यह भी समस्या है कि यदि tableView को नीचे तक स्क्रॉल किया गया है, और आप नियंत्रक और पॉप को पीछे धकेलते हैं, तो यह अब नीचे नहीं होगा।

override func viewDidLoad()
{
    super.viewDidLoad()

    // This parts gets rid of animation when pushing
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .never
    }
}

override func viewDidDisappear(_ animated: Bool)
{
    super.viewDidDisappear(animated)
    // This parts gets rid of animation when popping
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .never
    }
}

override func viewDidAppear(_ animated: Bool)
{
    super.viewDidAppear(animated)
    // This parts sets correct behaviour(insets are correct on iPhone X)
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .automatic
    }
}

पेरेंटव्यू क्या है?
फोनोनीवेल्टर

आपके दृश्य नियंत्रक का मुख्य दृश्य, मैंने उत्तर अपडेट कर दिया है। धन्यवाद।
एल

जब मैं UITableViewController का उपयोग कर रहा हूं तो तालिका दृश्य नियंत्रक का दृश्य है। इसके अलावा, डिवाइस को घुमाए जाने पर इनसेट अलग-अलग होने चाहिए। मुझे समायोजन चाहिए। जब टेबल पहली बार दिखाई देता है तो मुझे एनीमेशन पसंद नहीं है।
फॉनडेवेल्टर

आपके मामले में चूंकि UITableView नियंत्रक का दृष्टिकोण है, इसलिए इसमें safeAreaInsets.bottom = 34 (पोर्ट्रेट) होना चाहिए, ताकि आप बस tableView.contentInset = tableView.safeAreaInsets सेट कर सकें।
एल भयानक

यह मेरे लिए काम नहीं करता है। ViewDidLoad में सभी इनसेट शून्य हैं। अगर मैं उस कोड का उपयोग करने की कोशिश करता हूं, तो viewLillLayoutSubviews में स्क्रॉल इंडिकेटर को इनसेट मिल जाता है, लेकिन टेबल व्यू खुद क्षैतिज रूप से स्क्रॉल करने में सक्षम हो जाता है। यदि मैं समायोजन को अक्षम किए बिना viewWillLayoutSubviews में इनसेट्स को देखता हूं तो नीचे का समायोजन समायोजित हो जाता है। शुरुआत 21 हो जाती है और यह सब बदल जाता है।
फॉनडेवेल्टर


2

कृपया उपरोक्त कोड के साथ सुनिश्चित करें, अतिरिक्त कोड इस प्रकार जोड़ें। इसने समस्या को हल कर दिया

override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // print(thisUISBTV.adjustedContentInset) 
}

इसने अकेले ही मेरी समस्या हल कर दी !! धन्यवाद। इस मुद्दे पर कई घंटे बर्बाद!
मुरात यासर

2

यदि आप टैब बार का उपयोग करते हैं, तो संग्रह दृश्य का निचला कंटेंट इनसेट शून्य होगा। इसके लिए नीचे दिए गए कोड viewDidAppear में डालें:

if #available(iOS 11, *) {
    tableView.contentInset = self.collectionView.safeAreaInsets
}

2

मेरे मामले में यह काम किया (इसे viewDidLoad में डालें):

self.navigationController.navigationBar.translucent = YES;

1

के शीर्ष पर अतिरिक्त स्थान निकाला जा रहा है collectionViewयाtableView

    if #available(iOS 11.0, *) {
        collectionView.contentInsetAdjustmentBehavior  = .never
        //tableView.contentInsetAdjustmentBehavior  = .never
    } else {
        automaticallyAdjustsScrollViewInsets = false
    }

कोड से ऊपर collectionViewया tableViewनेविगेशन बार के तहत जाता है।
नीचे दिए गए कोड नेविगेशन के तहत जाने के लिए संग्रह दृश्य को रोकते हैं

    self.edgesForExtendedLayout = UIRectEdge.bottom

लेकिन मुझे UICollectionView के लिए तर्क और कोड के नीचे उपयोग करना पसंद है

एज इनसेट वैल्यू उस आयत द्वारा दर्शाए गए क्षेत्र को सिकोड़ने या विस्तारित करने के लिए एक आयत पर लागू होती है। आमतौर पर, एज इनसेट का उपयोग व्यू लेआउट को देखने के फ्रेम को संशोधित करने के लिए किया जाता है। सकारात्मक मान निर्दिष्ट राशि से फ्रेम को इनसेट (या सिकुड़) करते हैं। नकारात्मक मानों के कारण फ्रेम निर्दिष्ट राशि से शुरू (या विस्तारित) होता है।

collectionView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
//tableView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)

UICollectionView के लिए सबसे अच्छा तरीका है

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
}

0

मेरे लिए इस कोड काम को हटा दें

self.edgesForExtendedLayout = UIRectEdgeNone

0
  if #available(iOS 11, *) {
        self.edgesForExtendedLayout = UIRectEdge.bottom
  }

मैं कस्टम परिणाम के साथ UISearchController का उपयोग कर रहा था जिसमें तालिका दृश्य हैं। परिणाम नियंत्रक पर नए नियंत्रक को धक्का देने से खोज के तहत टेबलव्यू चला गया।

ऊपर सूचीबद्ध कोड ने समस्या को पूरी तरह से ठीक कर दिया

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.