2012-11-23 9 views
28

UICollectionView के शीर्ष पर मैं हेडर व्यू/टॉप व्यू (सेक्शन हेडर नहीं) कैसे जोड़ सकता हूं?UICollectionView में हेडर व्यू को कैसे जोड़ना है UITableView की तालिका हैडरर व्यू

यह UITableView की tableHeaderView संपत्ति के रूप में उत्कृष्ट रूप से कार्य करना चाहिए।

इसलिए इसे पहले सेक्शन हेडर व्यू (इंडेक्स 0 पर सेक्शन से पहले) के शीर्ष पर बैठने की ज़रूरत है, बाकी सामग्री के साथ स्क्रॉल करें, और उपयोगकर्ता इंटरैक्शन करें।

सबसे अच्छा मैं अब तक लेकर आए हैं पहले अनुभाग शीर्ष लेख का मानना ​​है कि काफी बड़ा भी शीर्षक में मेरी subviews को रोकने के लिए है के लिए (फ़ाइल के मालिक के रूप में UICollectionReusableView की MyCollectionReusableView उपवर्ग के साथ) एक विशेष XIB बनाने के लिए है, यह है एक हैक की तरह, मुझे लगता है, और मैं छूने का पता लगाने में कामयाब नहीं रहा है।

सुनिश्चित नहीं है कि अगर मैं स्पर्श करने की अनुमति देने के लिए अपना MyCollectionReusableView सबक्लास बना सकता हूं या बेहतर तरीका है।

उत्तर

5

मैंने संग्रह दृश्य के सबव्यूव के रूप में केवल UIView को जोड़कर संग्रह दृश्य के शीर्ष पर एक दृश्य डाला है। यह संग्रह दृश्य के साथ स्क्रॉल करता है और इसमें सामान्य UIView उपयोगकर्ता इंटरैक्शन है। यदि आपके पास कोई सेक्शन हेडर नहीं है, तो यह ठीक काम करता है, लेकिन यदि आप ऐसा करते हैं तो काम नहीं करता है। उस स्थिति में, मैं जिस तरह से कर रहा हूं उसके साथ मुझे कुछ भी गलत नहीं लगता है। मुझे यकीन नहीं है कि आप छूने का पता क्यों नहीं लगा रहे हैं, वे मेरे लिए ठीक काम करते हैं।

+0

धन्यवाद, मैं पहले ही सेक्शन हेडर का उपयोग करता हूं, इसलिए पहला (इंडेक्स 0 पर सेक्शन हेडर) मैंने मानक अनुभाग शीर्षलेख और संग्रह दृश्य के शीर्ष पर दृश्य दोनों को बड़ा करने के लिए बड़ा किया है। लेकिन आप कहते हैं कि आप अपने 'MyCollectionReusableView' subclass के अंदर छूते हैं? – ChrHansen

+0

बस वापस चला गया और फिर कोशिश की, और आप सही हैं - यह काम करता है! मैं बहुत देर से काम कर रहा था और मैंने स्पर्शों का पता लगाने के लिए 'UIImageView' का उपयोग किया और एक्सकोड में मेरे छवि दृश्यों के लिए "उपयोगकर्ता इंटरैक्शन सक्षम" पर टिक टिक भूल गया। – ChrHansen

51
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 320, self.view.frame.size.height) collectionViewLayout:flowlayout]; 
self.collectionView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0); 
UIImageView *imagev = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"015.png"]]; 
imagev.frame = CGRectMake(0, -50, 320, 50); 
[self.collectionView addSubview: imagev]; 
[self.view addSubview: _collectionView]; 

मैं विशेषता contentInset का उपयोग UICollectionView के शीर्ष करने के लिए एक फ्रेम डालने के लिए, तो मैं यह करने के लिए छवि दृश्य जोड़ने, और यह सफल होता है। मुझे लगता है कि यह UITableView की tableHeaderView संपत्ति के रूप में उत्कृष्ट रूप से कार्य कर सकता है। तुम क्या सोचते हो?

+0

मैं इसके लिए खोज रहा था, यह पहले सेक्शन हेडर को लंबा बनाने से कहीं बेहतर है। –

+1

इसके लिए धन्यवाद। –

+0

मैंने हेडर vie जोड़ने के लिए उपरोक्त तरीके से उपयोग किया है, हेडर व्यू पर टच इवेंट प्राप्त करने में सक्षम नहीं, कोई विचार क्यों? –

2

इसे प्राप्त करने का सबसे अच्छा तरीका पहले खंड के लिए सेक्शन हेडर बनाना है। तब UICollectionViewFlowLayout के गुण सेट:

@property(nonatomic) BOOL sectionHeadersPinToVisibleBounds 

या तेज

var sectionHeadersPinToVisibleBounds: Bool 

नहीं करने के लिए (स्विफ्ट के लिए गलत)। इससे यह सुनिश्चित होगा कि अनुभाग हेडर लगातार कोशिकाओं के साथ स्क्रॉल करता है और शीर्ष पर पिन नहीं किया जाता है जैसे कि सेक्शन हेडर सामान्य रूप से होता है।

+0

यह मेरे लिए काम करता है, लेकिन अगर मुझे कुछ अनुभाग चाहिए तो शीर्ष पर पिन किया गया है, लेकिन कुछ नहीं? यह UICollectionViewFlowLayout की संपत्ति वैश्विक सेट पसंद करती है। – Neko

-2
private var PreviousInsetKey: Void? 
extension UIView { 

var previousInset:CGFloat { 
    get { 
     return objc_getAssociatedObject(self, &PreviousInsetKey) as? CGFloat ?? 0.0 
    } 
    set { 
     if newValue == -1{ 
      objc_setAssociatedObject(self, &PreviousInsetKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
     } 
     else{ 
      objc_setAssociatedObject(self, &PreviousInsetKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
     } 
    } 
} 


func addOnCollectionView(cv: UICollectionView){ 
    if self.superview == nil{ 
     var frame = self.frame 
     frame.size.width = SCREEN_WIDTH 
     cv.frame = frame 
     self.addOnView(view: cv) 
     let flow = cv.collectionViewLayout as! UICollectionViewFlowLayout 
     var inset = flow.sectionInset 
     previousInset = inset.top 
     inset.top = frame.size.height 
     flow.sectionInset = inset 
    } 

} 

func removeFromCollectionView(cv: UICollectionView){ 
    if self.superview == nil{ 
     return 
    } 
    self.removeFromSuperview() 
    let flow = cv.collectionViewLayout as! UICollectionViewFlowLayout 
    var inset = flow.sectionInset 
    inset.top = previousInset 
    flow.sectionInset = inset 
    previousInset = -1 
} 

func addOnView(view: UIView){ 

    view.addSubview(self) 

    self.translatesAutoresizingMaskIntoConstraints = false 
    let leftConstraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0) 
    let widthConstraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.size.width) 
    let heightConstraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.size.height) 
    let topConstraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0) 

    view.addConstraints([leftConstraint, widthConstraint, heightConstraint, topConstraint]) 
    self.layoutIfNeeded() 
    view.layoutIfNeeded() 
} 
} 
+1

क्या आप कृपया बता सकते हैं कि आपका समाधान क्या कर रहा है? –

0

मैं सबसे अच्छा तरीका यह है कि यह UICollectionViewLayout (UICollectionViewFlowLayout) उपवर्ग को पूरा करने के लिए और की जरूरत हेडर या फुटर विशेषताओं को जोड़ने लगता है।

यूआईसीओलेक्शन व्यू लेआउट में पूरक दृश्य सहित सभी आइटम collectionViewLayout संपत्ति के अनुसार, यह collectionviewlayout है जो यह तय करता है कि कोई हेडर (पाद लेख) है या नहीं।

contentInset का उपयोग करना आसान है, लेकिन जब आप गतिशील रूप से हेडर को छिपाना या दिखाना चाहते हैं तो समस्या हो सकती है।

मैंने इसे पूरा करने के लिए एक प्रोटोकॉल लिखा है, जिसे यूआईसीओलेक्शन व्यूलाउट के किसी उप-वर्ग द्वारा अपनाया गया है ताकि इसे हेडर या पाद लेख बनाया जा सके। आप पा सकते हैं यह here.

मुख्य विचार हेडर के लिए एक UICollectionViewLayoutAttributes बना सकते हैं और layoutAttributesForElements(in rect: CGRect) में इसे वापस करने के लिए यदि आवश्यक हो तो, आप सभी अन्य विशेषताओं को संशोधित करना होगा है, अपने स्थानों के सभी शीर्ष लेख की ऊंचाई से नीचे ले जाया जाना चाहिए, क्योंकि हेडर उन सभी से ऊपर है।

0

मैं अपना कस्टम हेडर जोड़ने के लिए एक UICollectionView एक्सटेंशन का उपयोग कर समाप्त हुआ। एक विशिष्ट टैग का उपयोग करके, मैं अपने कस्टम हेडर (बाहरी से सभी पारदर्शी) की पहचान करने के लिए संग्रहीत संपत्ति को नकली करने में सक्षम हूं। यदि आप अपना कस्टम हेडर जोड़ते हैं तो UICollectionView का लेआउट पूरा नहीं होता है, तो आपको किसी विशिष्ट ऑफसेट पर स्क्रॉल करना पड़ सकता है।

extension UICollectionView { 
    var currentCustomHeaderView: UIView? { 
     return self.viewWithTag(CustomCollectionViewHeaderTag) 
    } 

    func asssignCustomHeaderView(headerView: UIView, sideMarginInsets: CGFloat = 0) { 
     guard self.viewWithTag(CustomCollectionViewHeaderTag) == nil else { 
      return 
     } 
     let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height 
     headerView.frame = CGRect(x: sideMarginInsets, y: -height + self.contentInset.top, width: self.frame.width - (2 * sideMarginInsets), height: height) 
     headerView.tag = CustomCollectionViewHeaderTag 
     self.addSubview(headerView) 
     self.contentInset = UIEdgeInsets(top: height, left: self.contentInset.left, bottom: self.contentInset.bottom, right: self.contentInset.right) 
    } 

    func removeCustomHeaderView() { 
     if let customHeaderView = self.viewWithTag(CustomCollectionViewHeaderTag) { 
      let headerHeight = customHeaderView.frame.height 
      customHeaderView.removeFromSuperview() 
      self.contentInset = UIEdgeInsets(top: self.contentInset.top - headerHeight, left: self.contentInset.left, bottom: self.contentInset.bottom, right: self.contentInset.right) 
     } 
    } 
} 

कस्टमकॉलिशन व्यूहेडर टैग आपके हेडर को दिए गए टैग नंबर को संदर्भित करता है। सुनिश्चित करें कि यह आपके UICollectionView में एम्बेडेड किसी अन्य दृश्य का टैग नहीं है।

संबंधित मुद्दे