UI Automation: which delegate methods are called when scrolling in a scrollview - iphone

I'm new to UIAutomation introduced by iOS4. I'm scripting a test which requires to scroll in a scrollview.
So UIAScrollView has the following methods:
scrollUp
scrollDown
scrollLeft
scrollRight
scrollToElementWithName
scrollToElementWithPredicate
scrollToElementWithValueForKey
I want to know which UIScrollView delegate methods are invoked in the app when using these functions in my script.

UI Automation has nearly nothing to do with your Application in fact you can even run automation for apps that aren't yours. Indeed you have to know the accessibility label for each element. Therefore it should call the normal UIScrollViewDelegate which contains:
Responding to Scrolling and Dragging
– scrollViewDidScroll:
– scrollViewWillBeginDragging:
– scrollViewDidEndDragging:willDecelerate:
– scrollViewShouldScrollToTop:
– scrollViewDidScrollToTop:
– scrollViewWillBeginDecelerating:
– scrollViewDidEndDecelerating:
Managing Zooming
– viewForZoomingInScrollView:
– scrollViewWillBeginZooming:withView:
– scrollViewDidEndZooming:withView:atScale:
– scrollViewDidZoom:
Responding to Scrolling Animations
– scrollViewDidEndScrollingAnimation:
simply implement all into your application and NSLog() which one gets called.
Not sure if that's what you wanted to know.

Related

What is the imagePickerController delegate method before the didfinishpickingmediawithinfo method is called?

So I have a visual cue (PNG rectangle lines) that pops up when taking a picture for this test app I’m doing.
So I remove the visual cue in the did finish picking media delegate method and/or the didcancel method as well. But I can’t find info on a delegate method for inbetween. Is there one? If there isn’t, is there a way to handle using a visual cue during image taking but not during the deciding “phase”?
I've looked at the Apple Docs but can't find anything so far. I'm trying to be better as far as attention to detail but I still struggle so my apologies if I didn't see it
I don't think there's code necessary to show so I can't show sample code.
No, the only delegate methods are imagePickerController(_:didFinishPickingMediaWithInfo:) and imagePickerControllerDidCancel(_:).
If you want to customize the user interface during picture taking, you can take a few approaches.
First, use the cameraOverlayView property to customize the UI.
Second, note that the UIImagePickerController is itself a UINavigationController. You can therefore set its delegate and respond to navigationController(_:willShow:animated:) to be notified when the user is about to move between view controllers. You could implement logic here to show, hide, or otherwise adjust your custom UI.

showing touches on iOS device like in the simulator

For the purposes of making app demos and presentations, I would like to draw circles corresponding to touches, just like in the iOS simulator, but on the device itself.
Ideally, this would be orthogonal to other code. Perhaps a UIView which draws the circles and forwards the events, but event forwarding seems to require the other views be aware:
http://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html#//apple_ref/doc/uid/TP40009541-CH3-SW17
Is there a clean way of doing this?
(I can't use the simulator for demos because my app uses gestures, MIDI, and OpenGL)
thanks!
There is a framework call fingertips which is available through cocoapods.
http://cocoapods.org/?q=on%3Aios%20fingertips
This will do what you are asking.
I don't think there's a clean way of doing this. However, this is what I would try:
Use method swizzling to hook up to all your views by swizzling the methods
- touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
for the UIView class. In addition, you may also need to swizzle some methods of UIGestureRecognizer subclasses, since they may prevent the methods listed above from being called. This way you can do your own thing (e.g. draw the touch points on the screen), and also let the views handle the touches as before.

UIScrollView notifications

I'm coding an app that works much like Apple's Weather.app: There's a UIPageControl at the bottom and a UIScrollView in the middle of the screen.
In my code, I implemented the - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView method to figure out when the user did move to a new page. If they move to a new page, I load the adjacent pages' data, as to make further page-switching faster. (In one of Apple's examples, the - (void)scrollViewDidScroll:(UIScrollView *)sender is used, but that causes my app to shortly hang when loading a new page, so it's not suitable.)
That code works very well.
I'm using scrollRectToVisible:: to programmatically scroll inside the scrollview when the user clicks the UIPageControl. The problem is that the scrollRectToVisible: doesn't post a notification to the UIScrollViewDelegate when it's done scrolling - so the code responsible for loading adjacent pages never get's called when using the UIPageControl.
Is there any way to make the UIScrollView notify its delegate when it gets called by the scrollRectToVisible: method? Or will I have to use threads in order to prevent my app from freezing?
Thanks!
-- Ry
How about -scrollViewDidEndScrollingAnimation:?
If it doesn't work, try to listen to the UITextSelectionDidScroll notification. (Of course, it's undocumented.)
Alternatively, an SDK-safe method is measure the time taken for the animation and send a delayed notification at the call site of -scrollRectToVisible:.
You could add this delegate method instead:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
The scroll view calls this method at the end of its implementations of the UIScrollView and setContentOffset:animated: and scrollRectToVisible:animated: methods, but only if animations are requested.

What are the differences between the interface orientation delegate methods

anyone can tell differences among
willRotateToInterfaceOrientation,
willAnimateRotationToInterfaceOrientation,
didRotateFromInterfaceOrientation,
iOS originally did all rotations in a two-step process. In iOS 3.0, a new/better one-step animation process was introduced. The methods you mention are called at different stages in rotation. Specifically,
willRotateToInterfaceOrientation:duration: is called whenever the view is going to rotate (using any rotation method), before any rotation is started. This method will be called on ANY version of iOS, ANY time a rotation is performed (on an actively-shown view)
willAnimateRotationToInterfaceOrientation:duration: is called during a one-step rotation operation, just before the animation is drawn. This will only be called on iOS 3.0+.
didRotateFromInterfaceOrientation: is called at the end of a rotation operation (using any rotation method), after the rotation is complete. This method will be called on ANY version of iOS, ANY time a rotation is performed (on an actively-shown view).
In practice, on any modern (3.0+) iOS, all three methods are sent to the view controller of the actively-shown view. The methods are called in the order listed:
willRotateToInterfaceOrientation:duration: first
willAnimateRotationToInterfaceOrientation:duration: second,
didRotateFromInterfaceOrientation: last
Note: iOS 5 deprecates the other rotation-notification methods (dealing with the two-step animation process), so these three are the only ones that should be used in new projects.
From the UIViewController Class Reference:
willRotateToInterfaceOrientation:duration:
Sent to the view controller just
before the user interface begins
rotating.
willAnimateRotationToInterfaceOrientation:duration:
Sent to the view controller before
performing a one-step user interface
rotation.
didRotateFromInterfaceOrientation:
Sent to the view controller after the
user interface rotates.
The most significant difference I think is when method willRotateToInterfaceOrientation:duration: is called the self.view.bounds doesn't change but when method willAnimateRotationToInterfaceOrientation:duration: is called self.view.bounds has changed

Deferring viewWillAppear until webViewDidFinishLoad

I have an application that uses UIWebViews in several view controllers. The UIWebViews are used to render locally generated html, no slow network access required.
To save memory I only load these on demand as prompted by the viewcontroller viewWillAppear callback. (And unload offscreen instances in response to didReceiveMemoryWarning messages.)
The problem is that the user gets to see the html being rendered, sometimes accompanied by flashes of styling and other assorted unpleasant artifacts. I would much rather the rendering be done offscreen, and reveal the fully rendered view when its ready.
It would be very tidy to be able to have the viewWillAppear not return until the UIWebView is fully rendered. But how?
I tell the UIWebView what to render by sending it a loadHTMLString:baseURL: message. This is asynchronous, and some time (soon) later the webview's delegate gets called back webViewDidFinishLoad.
I experimented with running a runloop inside viewWillAppear, running either the NSDefaultRunLoopMode or UITrackingRunLoopMode. This works in the simulator (it complains to the log
[CATransaction synchronize] called within transaction
but does work) but on a device it deadlocks, with webViewDidFinishLoad never being called.
(Also, it seems like the UIWebView loading property doesn't work. At least, after I call loadHTMLString:baseURL: and before getting the callback it's not true.)
Lots of solutions here I think. A quick one is to load your UIWebView with it's hidden property set to YES. Then set your UIViewController as the UIWebViews delegate and implement:
- (void)webViewDidFinishLoad:(UIWebView *)webView
where you set the property back to NO.
A thing to note is that webViewDidFinishLoad will fire more than once if you have framed/embedded content. So you have to keep track of this. Shouldn't really be a problem if you are loading local content.
I like monowerker's solution best, but another solution would be to hold onto the already-rendered UIWebView all the time (in some more permanent object than the view controller). I'd only do that if the look of monowerker's solution is too disruptive.