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
Post a Comment