I'm still new to Objective C, and I feel this might be a probably a basic concept I don't know.
I'm working with OpenGL and I have the method GLKView of the viewcontroller, is called when "the view needs to be updated". From this method, I call another method, but I don't want the second method to be called at a rate that I specify.
How would I go about accomplishing this? I understand that viewcontroller.preferredFramesPerSecond can be set, but I only want this ONE specific method to work on a different timer..
Is this even the right way of going about this?
Sounds like you might want to use NSTimer
Related
Say I am switching Views via a segue and I know that most of the data I want to pass to a new VC will get passed to multiple other VCs in later segues. I am pretty new to swift/cocoa development, but as far as I am concerned, the standard way of passing this data would be via the prepareForSegue function. This seems to be pretty repetitive though, as I am passing the same data over and over again. Wouldn't it be easier to have some kind of singleton class to store that data and manipulate it with the current VC? I'm pretty sure Apple has a better solution for this though.
Is it ok to use singletons for this kind of scenario or is there a better way?
Singletons can be accessed directly from anywhere in the app. Singletons introduce coupling in your code and make your objects hard to test.
There are two ways to pass data forward.
Passing data when a segue is performed
Passing data when a transition is performed through code
Both could be boring but I think there is no way except them.
I'm using CCAnimate to animate my CCAnimations. What I want is reuse CCAnimate action, so, when I want to play another animation I do something like:
[_animateAction setAnimation:animation];
This works more ore less, the problem is that the internal elapsed time for the animation is not reset, setAnimation is just setting the new animation. Is there any way reset an action in cocos2D? I have been lurking through the code and documentation, and it doesn't seem to exist any method to accomplish this.
Does anyone know what is the "best practice" in this situation?.
There's been a lot of confusion about reusing actions in Cocos2D. Apparently the docs say you should "initialize" the action again but this may not be working for all actions and it's definitely considered a bad practice to send the "init…" message to an already existing object again. This is similar to how you're not supposed to send dealloc manually to an object, yet you can do it.
Nevertheless, that's the way it is supposed to be for Cocos2D actions, so in your case to re-use the same animation action you would have to send it the appropriate init… message again:
[animation initWithDuration:5 animation:anim restoreOriginalFrame:YES];
[_animateAction setAnimation:animation];
As a side note, there's been a suggestion for mutable actions in the Cocos2D issue tracking system for two years now. The submitted code patch isn't going to work without modifications with the current Cocos2D version but it may be used to create your own mutable actions should the need arise.
Suppose I want to reset an object to its initial state. It seems like the natural thing to do would be to run it through its init method -- but Apple guidelines are that I only want to do this once.
Creating a new object is not a satisfactory solution, because I need to preserve pointers to the object from elsewhere.
The object is part of a large class hierarchy. I will probably want to be able to reset most anything in the hierarchy.
Suggestions?
Create a reset method. This method could then in turn be called by init and if it is in a hiearchy all classes should implement it and call super reset.
UIView's that don't handle their events pass them up the chain. By default, this passes them to their parent View, and if not handled (ultimately) to their parent UIViewController.
UIScrollView breaks this (there's lots of questions on SO, variations on the theme of "why does my app stop working once I add a UIScrollView?)
UISV decides whether the event is for itself, and if not, it passes it DOWN (into its subviews); if they don't handle the event, UISV just throws it away. That's the bug.
In that case, it's supposed to throw them back up to its own parent view - and ultimately parent UIVC. AFAICT, this is why so many people get confused: it's not working as documented (NB: as views are documented; UISV simply is "undocumented" on this matter - it doesn't declare what it aims to do in this situation).
So ... is there an easy fix for this bug? Is there a category I could write that would fix UISV in general and avoid me having to create "fake" UIView subclasses who exist purely to capture events and hand them where they're supposed to go? (which makes for bug-prone code)
In particular, from Apple's docs:
If the time fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view. If the user then drags their finger far enough before the timer elapses, the scroll view cancels any tracking in the subview and performs the scrolling itself.
...if I could override that "if the timer fires" method, and implement it correctly, I believe I could fix all my UISV instances.
But:
- would apple consider this "using a private API" (their description of "private" is nonsensical in normal programming terms, and I can't understand what they do and don't mean by it)
- does anyone know what this method is, or a good way to go about finding it? (debugging the compiled ObjC classes to find the symbol names, perhaps?)
I've found a partial answer, that's correct, but not 100% useable :(.
iPhone OS 4.0 lets you remotely add listeners to a given view, via the UIGestureRecognizer class. That's great, and works neatly.
Only problem is ... it won't work on any 3.x iPhones and iPod Touches.
(but if you're targetting 4.0 and above, it's an easy way forwards)
EDIT:
On OS 3.x, I created a custom UIView subclass that has extra properties:
NSObject *objectToDelegateToOnTouch;
id touchSourceIdentifier;
Whenever a touch comes in, the view sends the touch message directly to the objectToDelegateToOnTouch, but with the extra parameter of the touchSourceIdentifier.
This way, whenever you get a touch, you know where it came from (you can use an object, or a string, or anything you want as the "identifier").
i.e. I have a layer's "transform.rotation.z" value which may change several times. Every time that value changes, I'd like to call a method. Of course I could call it just at any point where I touch that value. But maybe there's a more elegant way in objective-c / cocoa-touch? Somebody told me a few days ago that there's some notification mechanism available. But is that useful for something like this? How would it look like?
I think what you want is Key-Value Observing.