Friday, 15 August 2014

ios - Complex layout in UIView that animates its content -



ios - Complex layout in UIView that animates its content -

i'm having general question problem arises when i'm designing complex uiviews require special layout , animations @ same time.

what i'm building same kind of view mail service app uses on ios nowadays list of recipients when writing email (the bluish badges container) :

so understand , know how build such view, have question when facing such case : how handle complex layout (layouting bluish rounded rectangles) , animations @ same time (when adding or removing recipient) ?

1. reimplement :

- (void)layoutsubviews

to reflect state of view @ layout moment (ie layout each bluish rounded uibutton side side) according current bounds , add together , animate uibutton when adds new person list.

but happen animation if layout pass running? (this may dumb question since supposed happen on main thread , no concurrency involved here, i'm not sure on how handle this)

i think 2 things (layout , animations) not supposed happen @ same time, since main runloop "enqueues work , dequeues work" 1 "block" @ time (but maybe animation hundreds of blocks enqueued draw different things overtime, compromised layout block in between??)

2. also, solution acceptable ?

reimplement layoutsubviews exact same way handle right layout of subviews

when adds or deletes person, phone call re-position animated

[uiview animatewithduration:0.25f animations:^{ [self setneedslayout]; [self layoutifneeded]; }];

as can see, lots of questions here, don't know how handle gracefully.

both of these solutions have been tested , approved thing 1 best ?

do have improve solution ?

thanks help!

as understood, mean animations applied view layoutsubviews method implemented, e.g. animated alter of frame. if changed in view while animation ongoing causes view re-layout, layoutsubviews method called.

basically, such kind of animations nil more following:

change view's frame (actually, frame of view's layer) little value (e.g. increment origin's y coordinate 1 pixel) call layoutsubviews, if needed redraw view (i.e. layer) change view's frame little value call layoutsubviews, if needed redraw view ... repeat steps above until view's properties reach target values

all steps performed on main thread, steps above consecutive , not concurrent.

generally speaking, layoutsubviews method should define coordinates , sizes of subviews basing on own bounds. animations alter view's frame , correspondingly bounds, implementation of layoutsubviews method supposed handle changes correctly.

that is, reply question implement correctly layoutsubviews method.

p.s. this answer has great explanation of how animations implemented.

update

it seems understood question incorrectly. understanding was:

what happens if layoutsubviews method called view beingness animated? is, assumed there view e.g. changes y coordinate animation, layoutsubviews method called view during animation, , subview of view changes position in layoutsubviews.

after clarification @nicolas, understanding follows:

let's have view ('parent') subview ('child'); let's animate subview ('child'); let's phone call layoutsubviews method of 'parent' view , alter 'child' subview's frame in layoutsubviews method while animation ongoing. happen?

background theory:

uiview doesn't render content; it's done core animation layers. each view has associated calayer holds bitmap snapshot of view. in fact, uiview lean component above core animation layer performs actual drawing using view's bitmap snapshots. such mechanism optimizes drawing: rasterized bitmap can rendered graphics hardware; bitmap snapshots unchanged if view construction not changed, 'cahced'.

core animation layers hierarchy matches uiview's hierarchy; is, if uiview has subview, core animation layer corresponding container uiview has sublayer corresponding subview.

well... in fact, each uiview has more 1 corresponding calayer. uiview hierarchy produces 3 matching core animation layers trees:

layer tree - these layers used utilize through uiview's layer property presentation tree - layers containing in-flight values running animations. whereas layer tree objects contain target values animation, objects in presentation tree reflect current values appear onscreen. should never modify objects in tree. instead, utilize these objects read current animation values, perhaps create new animation starting @ values. objects in render tree perform actual animations , private core animation.

change of uiview's properties such frame alter of calayer's property. is, uiview's property wrapper around corresponding calayer property.

animation of uiview's frame alter of calayer's frame; frame of layer layer tree set target value whereas alter of frame value of layer presentation tree stretched in time. next call: [uiview animatewithduration:5 animations:^{ cgrect frame = self.label.frame; frame.origin.y = 527; self.label.frame = frame; }]; doesn't mean self.label's drawrect: method called multiple times during next 5 seconds; means y-coordinate of presentation tree's calayer corresponding self.label alter incrementally initial target value during these 5 seconds, , self.label's bitmap snapshot stored in calayer redrawn multiple times according changes of y-coordinate.

answer:

given background, can reply original question.

so, have ongoing animation kid view, , layoutsubviews method gets called parent view; in method, kid view's frame gets changed. means frame of layer assiciated kid view set new value. @ same time, layer presentation tree has intermidiate values (according ongoing animation); setting new frame changes target value presentation tree layer, animation go on new target.

that is, result of situation described in original question 'jumping' animation. please see demonstration in github sample project.

solution such complex cases

in layoutsubviews method, if animation ongoing, need utilize in-flight animation coordinates. can obtain them presentationlayer method of calayer associated view. is, if view beingness animated called aview, presentation layer view can accessed using [aview.layer presentationlayer].

ios iphone animation layout uiview

No comments:

Post a Comment