osx - Cocoa / Core Animation: everything jumps around upon becomeFirstResponder() -
the gist: have bunch of views nested in 1 mainview
. when call becomefirstresponder()
on nstextfield
that's nested in 1 of views, every view within mainview
jumps semi-arbitrary older position.
the actual cause 1 of number of things, leading among i've been writing cocoa week.
here's actual structure:
mainview: nsview ├ contacttile: nsview (layer-backed) | └ /* several calayers */ ├ contacttile ├ … ├ contacttile └ statustile: nsview (layer-backed) ├ searchicon: nsview (layer-backed) | └ searchiconlayer: calayer └ nstextfield
i've backed core business logic reactivecocoa, async dispatches main ui thread doing drawing-related operations.
the statustile
initialized , added subview when mainview
created, , position set top-right area of screen. contacttiles
created , added dynamically — creation , subview adding happens in 1 reactivecocoa observer (leaving initial position (0, 0)
), , in "relayout" observer contacttile
s statustile
animated , positioned code looks like:
let anim = cabasicanimation.init(keypath: "position"); let (from, to) = /* bunch of positional calculation */; anim.fromvalue = nsvalue.init(point: from); anim.tovalue = nsvalue.init(point: to); tile.layer!.removeanimation("contacttile-layout"); tile.layer!.addanimation(anim, forkey: "contacttile-layout"); tile.layer!.position = to;
this works long don't becomefirstresponder
; tiles animate , expected positions, , stay there expected. if check in on .position
@ rest, they're i'd expect.
but add code in separate reactivecocoa observer listens global hotkey. global hotkey signal triggers relayout @ same time, causing animation/layout code see above go. triggers separate observer calls textfield.becomefirstresponder()
in statustile
view above.
globalinteraction.sharedinstance.activated.observenext { activated in if activated { dispatch_async(dispatch_get_main_queue(), { self._searchfield.becomefirstresponder(); }); } else { self._searchfield.stringvalue = ""; } }
now happens animation proceeds expected, upon animation completion, each element resets initial position described few paragraphs ago: statustile
reverts initial top-right position, , every contacttile
reverts (0, 0)
.
if check on actual .position
s @ rest, indeed report (0, 0)
. if check .position
after calculation block above, i'd expect be. weirder, .becomefirstresponder()
call pretty consistently happens before perform relayout animation setup above. somehow call messes positions after said , done far code concerned.
when subsequently happens changes layout, typing in text field or other external inputs, goes working expected, while text field has focus. it's on initial activation bounces around.
some possibly related quirks:
- i'm rendering onto transparent, borderless window, floating in space.
- the application in general receives focus part of same global hotkey.
- ?? not sure else, it's kind of strange application , i'm new cocoa, please ask if have clarifying questions.
Comments
Post a Comment