ios - JSQMessagesViewController with SupplementaryView fixed on top -


have overridden collectionview:viewforsupplementaryelementofkind:atindexpath: show header view jsqmessagesviewcontroller subclass in swift. works well, header view scrolls chat, , have fixed on top.

apple introduced in ios 9 sectionheaderspintovisiblebounds property, , should have fixed header view, reason doesn't work in jsqmessagesviewcontroller subclass. have added self.collectionview.collectionviewlayout.sectionheaderspintovisiblebounds = true viewdidload()

another solution tried (from post how make supplementary view float in uicollectionview section headers in uitableview plain style), subclass jsqmessagescollectionviewflowlayout, , worked. when swiping up, header view stays fixed on top, , chat messages pushed under header view. try swipe down, receive following error in console when app crashes:

*** assertion failure in -[uicollectionviewdata validatelayoutinrect:], /buildroot/library/caches/com.apple.xbs/sources/uikit/uikit-3512.60.12/uicollectionviewdata.m:408 *** terminating app due uncaught exception 'nsinternalinconsistencyexception', reason: 'layout attributes supplementary item @ index path (<nsindexpath: 0xc000000000000016> {length = 2, path = 0 - 0}) changed <jsqmessagescollectionviewlayoutattributes: 0x13f65a730> index path: (<nsindexpath: 0xc000000000000016> {length = 2, path = 0 - 0}); element kind: (uicollectionelementkindsectionheader); frame = (0 0; 414 100); zindex = 10;  <jsqmessagescollectionviewlayoutattributes: 0x13f679920> index path: (<nsindexpath: 0xc000000000000016> {length = 2, path = 0 - 0}); element kind: (uicollectionelementkindsectionheader); frame = (0 10; 414 100); zindex = 1024;  without invalidating layout' 

have had success fixing header view in same way jsqmessagesviewcontroller?

the methods changed shouldinvalidatelayoutforboundschange: returned yes,

and layoutattributesforelementsinrect: changed to:

- (nsarray *)layoutattributesforelementsinrect:(cgrect)rect {     nsmutablearray *attributesinrect = [[super layoutattributesforelementsinrect:rect] mutablecopy];  //    if (self.springinessenabled) { //        nsmutablearray *attributesinrectcopy = [attributesinrect mutablecopy]; //        nsarray *dynamicattributes = [self.dynamicanimator itemsinrect:rect]; //         //        //  avoid duplicate attributes //        //  use dynamic animator attribute item instead of regular item, if exists //        (uicollectionviewlayoutattributes *eachitem in attributesinrect) { //             //            (uicollectionviewlayoutattributes *eachdynamicitem in dynamicattributes) { //                if ([eachitem.indexpath isequal:eachdynamicitem.indexpath] //                    && eachitem.representedelementcategory == eachdynamicitem.representedelementcategory) { //                     //                    [attributesinrectcopy removeobject:eachitem]; //                    [attributesinrectcopy addobject:eachdynamicitem]; //                    continue; //                } //            } //        } //         //        attributesinrect = attributesinrectcopy; //    }     uicollectionview * const cv = self.collectionview;     cgpoint const contentoffset = cv.contentoffset;     nsmutableindexset *missingsections = [nsmutableindexset indexset];       (uicollectionviewlayoutattributes *layoutattributes in attributesinrect) {         if ([layoutattributes.representedelementkind isequaltostring:uicollectionelementkindsectionheader]) {             [missingsections removeindex:layoutattributes.indexpath.section];         }     }      [attributesinrect enumerateobjectsusingblock:^(jsqmessagescollectionviewlayoutattributes *attributesitem, nsuinteger idx, bool *stop) {         if (attributesitem.representedelementcategory == uicollectionelementcategorycell) {             [self jsq_configuremessagecelllayoutattributes:attributesitem];             [missingsections addindex:attributesitem.indexpath.section];         }         else {             attributesitem.zindex = -1;         }     }];      [missingsections enumerateindexesusingblock:^(nsuinteger idx, bool *stop) {         nsindexpath *indexpath = [nsindexpath indexpathforitem:0 insection:idx];         uicollectionviewlayoutattributes *layoutattributes = [self layoutattributesforsupplementaryviewofkind:uicollectionelementkindsectionheader atindexpath:indexpath];         [attributesinrect addobject:layoutattributes];     }];      (uicollectionviewlayoutattributes *layoutattributes in attributesinrect)  {         if ([layoutattributes.representedelementkind isequaltostring:uicollectionelementkindsectionheader]) {             nsinteger section = layoutattributes.indexpath.section;             nsinteger numberofitemsinsection = [cv numberofitemsinsection:section];             nsindexpath *firstcellindexpath = [nsindexpath indexpathforitem:0 insection:section];             nsindexpath *lastcellindexpath = [nsindexpath indexpathforitem:max(0, (numberofitemsinsection - 1)) insection:section];             nsindexpath *firstobjectindexpath = [nsindexpath indexpathforitem:0 insection:section];             nsindexpath *lastobjectindexpath = [nsindexpath indexpathforitem:max(0, (numberofitemsinsection - 1)) insection:section];             uicollectionviewlayoutattributes *firstobjectattrs;             uicollectionviewlayoutattributes *lastobjectattrs;             if (numberofitemsinsection > 0) {                 firstobjectattrs = [self layoutattributesforitematindexpath:firstobjectindexpath];                 lastobjectattrs = [self layoutattributesforitematindexpath:lastobjectindexpath];              } else {                 firstobjectattrs = [self layoutattributesforsupplementaryviewofkind:uicollectionelementkindsectionheader atindexpath:firstobjectindexpath];                 lastobjectattrs = [self layoutattributesforsupplementaryviewofkind:uicollectionelementkindsectionfooter atindexpath:lastobjectindexpath];             }             cgfloat headerheight = cgrectgetheight(layoutattributes.frame);             cgpoint origin = layoutattributes.frame.origin;             origin.y = min(max(contentoffset.y + cv.contentinset.top, (cgrectgetminy(firstobjectattrs.frame) - headerheight)), (cgrectgetmaxy(lastobjectattrs.frame) - headerheight));             layoutattributes.zindex = 1024;             layoutattributes.frame = (cgrect) {                 .origin = origin, .size = layoutattributes.frame.size             };         }     }        return attributesinrect; } 

the code presented above ok. caused crash think because had overridden collectionview:collectionviewlayout:referencesizeforheaderinsection: function in jsqmessagesviewcontroller subclass. commented out function, , instead set height in kjsqmessagesloadearlierheaderviewheight constant in jsqmessagesloadearlierheaderview. yes, hijacked loadearlierheaderview show own custom header view.

now, header view pinned top, showing custom headerview, , without crash.


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -

java - Digest auth with Spring Security using javaconfig -