I have been working on an iOS, OpenGL-based app for the past few months. During this time, I have created both the main UIWindow and a single UIView in code, as opposed to using a storyboard. An important item to note is that I create an instance of EAGLView (used in many Apple examples), which inherits from UIView.
The code base I am working with is quite extensive, and among other things, it uses a separate rendering thread. I'll come back to this point near the end of this post.
With this in mind, I am now at the point that I want to add native UI support. To do this, I am using a storyboard (for the first time). My current setup consists of a main/root view with two buttons. Each button uses a modal segue to place a new view on the screen.
To reuse as much code as possible, I have specified that the views I segue to are of type EAGLView (as opposed to UIView). The only change I've had to make is that instead of initializing with "initWithFrame", I now initialize with "initWithCoder".
Other than moving to a storyboard, nothing else in the code base has changed. However, when I segue to an EAGLView, nothing renders -- all I see is white. I am hesitant to use GLKit because it duplicates much of the functionality I have already written (I had everything rendering just fine prior to using a storyboard). In addition, GLKit provides a callback for rendering, whereas, I have a separate render thread.
My scenario sounds a lot like this post:
OpenGL iOS view does not paint
I have GL error checks for every call (or for every group of calls), and no errors are being reported. What's even stranger is that when I capture an OpenGL ES frame for debugging (in Xcode), the debugger actually shows the content I expect to see.
Any ideas here? I am stumped.
Please try the following:
Verify that you stop rendering in the view that you're segueing from (stopping times etc.) - this view is still alive since you only pushed a new EAGLView on top of it.
Use XCode's OpenGL ES Frame capture to debug your OpenGL state in the new view. Verify that you're not missing binding to textures or other objects.
If the above doesn't work - write the simplest rendering possible (simple quad, for example) and debug that code.
Related
I want to create a simple game, and as I understand it OpenGL will make that happen but could I make the menu, high score list and every thing except the game with regular xcode?
For instance, for Windows Phone (where im comming from) you could create XAML/DirectX where you totally could make the menu in xaml/cs and then the game in directx
Yes, the main view element in iOS is called an UIView and you use it to present openGL content on it. This results in being able to overlay it with any other views, subviews, put it in a superview, have multiple views with openGL content... All the events such as touches work as well. In summery implementing openGL in iOS UIView will simply override the visual content of the view leaving rest of the functionality as it is.
I'm looking for a technique to progressively load in the contents of a UIViewController to make an app feel "snappier". I noticed this issue when pushing a viewcontroller onto the stack there's a noticeable delay while waiting for it to push in. The UIViewController's View has some complex subviews with transparency. I'm wondering if I create them after viewDidAppear and 'fade' them in, then the transition will appear much smoother.
I noticed a similar effect in Apple's Trailers app. When tapping a movie in that app the detail view pushes in and the contents load after the fact. Granted part of that delay is because they are downloading the details before showing them, but it seems like they always fadein that large image whether it's been downloaded already or not.
Has anyone had much success with this or with improving UIViewController loads in general.
Before you start making changes in an effort to improve performance, use Instruments to profile your app and find out where the problem really is. Is it in drawing the complex subviews? Is it in loading the data? The only way to know is to measure.
There's no reason you couldn't do as you propose -- have the view controller create/load its main view and then add the complex subviews afterward. Your view controller can add and remove subviews at will. Will that make the app feel snappier? It might -- it's similar to the default image strategy Apple built into iOS, where the OS loads a picture of your interface to make the device seem responsive, and then substitutes the real interface once that's ready. On the other hand, if the user still has to wait for the complex subviews to be created before the view is useful, seeing the rest of the view might not help much.
Another possibility (again, after measuring) might be to create the views before the user needs them. This runs counter to the lazy initialization that iOS apps commonly use to conserve memory and power, but if you know that you're going to need the views and you can expect a lull in user activity before they're needed, it could be a good way to increase the app's apparent speed. All you need to do to get a view controller to create/load its view is to access its view property.
I have this problem with performance of my iPad app..
For developing, I use MonoDevelop, which takes care of Garbage collecting. Still my questions are rather generic, I'd say.
OK, I use TabBarController with 5 NavigationControllers. Inside nav controllers there are some controllers, whose views are TableViews or ScrollViews. Next child is always just regular view.
I have a few questions:
1) TableViews never scroll smoothly. I have some alpha transparency, but since I did my graphics in Photoshop and not programmatically, this transparency should not cause much problems. It doesn't matter whether I have few or many results in table.
On the other hand, I have ScrollView which serves same purpose, i.e. to be a table with different layout and buttons have Photoshop generated transparency as well. It works perfectly.
For tables I applied DequeueReusableCell() which works fine (I see that memory usage is not increasing after scrolling). So why would tables scroll so jerky?
2) My app supports rotation. When I scroll table or scrollView and simultaneously tilt the device a bit, I get maybe 1 or 2 FPS. What is the best way to implement rotation? As I understand, ShouldAutorotateToInterfaceOrientation has to be overridden in all controllers in NavigationController chain. Also, I need to add observer in View I want some changes to happen. Do I have to use BeginGeneratingDeviceOrientationNotifications() in all views or is it enough to do it in Main.cs? Maybe this slows it down?
3) After some time app starts getting memory warnings and then crashes eventually. I tried to read logs and run app with Instruments, but can't find the cause of crash.
4) What exactly happens to a View popped from NavigationController stack? I can't reuse it. But could it be that Monotouch (or me) doesn't dispose it correctly?
I have almost same app for iPhone without support for rotation which never crashes. I think I'm doing something wrong with this rotation, but I'm not sure what.
Any help will be appreciated the most. So, thank you in advance.
Regards
1 - transparencies are always a problem. Even if you're not rendering the images in code, the phone still needs to do the compositing of the image, and that may take a lot of time. UITableViews have to calculate the final composite image every time a new cell is displayed, or the table is scrolled, while UIScrollViews can calculate only once, since the image won't change. So be very careful about it, turn the transparency off, and check if performance improves.
2 - You shouldn't need to notify every uiview in your application. Receive the notification in the controllers that you want to update only, like for example if you want to rearrange items in the UIViewControllers view.
3 - you have one (or many) memory leaks. My guess is that MonoTouch probably can't garbage collect UIViews or UIViewControllers, because they're still being linked from somewhere in UIKit, like a UINavigationController
4 - UIViews are not disposed by UIKit until the app gets a memory warning notification.
Like Eduardo said, alpha transparency in Views comes at a price. There are some tools that you can use to identify the bottlenecks discussed in these WWDC 2011 talks from:
https://developer.apple.com/videos/wwdc/2011/
iOS Performance and Power Optimization with Instruments
Understanding UIKit Rendering
In the "Debug" menu of the iOS simulator you can find various debugging tools that will color different regions of the screen indicating where some problematic rendering is taking place. The WWDC 2011 talks show what you can do to fix those problems.
For your memory problems, it is very likely that you have something pointing out to your objects around, so you need to make sure those objects are gone. While we currently are not shipping our new profiler for MonoTouch that can show the source of the problem, I wrote a "poor man's" debug utility that will help you narrow down which objects are alive. It is available here:
http://tirania.org/tmp/HttpDebug.cs
Call HttpDebug.Start () from your application and as you run, connect with a web browser to http://localhost:5000 to get a list of live Objective-C objects surfaced to C#. The tool is not perfect and shows a lot of irrelevant data, but it would at least give you an idea of what is going on.
I am trying to use OpenGL to paint a view which is a subview of another view. I have created a view class for this purpose, and if I use this class in a simple test application it works fine. However, if I place an instance of this class on a particular page of my app, the OpenGL painting does not display anything. I am certain that the view is visible (I can set a background color, and that is displayed, and I can receive touch events). I can also trace through the OpenGL initialization and paint routines, and everything seems fine. My paint routine IS being called, and I call glGetError frequently and no errors are returned. I can compare tracing the routine with the case that works, and everything seems pretty much the same, but nothing paints (I even have simply tried doing nothing but clearing the window to black but that does nothing either).
The code for the app that does not work is far to complex to post here. I assume that I am doing something wrong, but for the life of me I cannot figure out what. Can anyone give me any ideas about why the OpenGL painting would appear to succeed and yet not draw anything, or suggest a strategy for figuring this out?
Thanks.
The link between OpenGL and the outside world is platform specific and not part of the core API. So a problem there wouldn't affect the result of glGetError.
In the case of iOS the relevant call is EAGLContext -presentRenderbuffer:, which will work provided you've used renderbufferStorage:fromDrawable: to create storage for a render buffer from a CAEAGLLayer. You probably want to inspect the return result of presentRenderbuffer: and the code around that to look for an error rather than the internal GL state.
I am currently working on an iPhone 2.1 application. I am new to Objective C, coming from a Java background.
My application has as a base the Utility Application template available in Xcode with the iPhone SDK. Currently I have some controls, such as an UISlider and text box, in the FlipsideView. The UISlider already has a method which is being called when the value changes, using targets and selectors. However, I would also like to be able to read, from the MainView, the current (or last) value of the UISlider and textbox.
Keep in mind I am new to development on a Mac, and would appreciate any guidance as to where I should look up such information, be it through the use of delegates or perhaps I am missing something obvious in the structure of the template.
UPDATE:
I am taking a look at the structure and have some more details: The UISlider is being created in FlipsideView.m. I noticed that the Done button is created from RootViewController.m and probably I should move the UISlider code over there. I may incorrectly be using the View to keep code that would be more appropiate in a Controller.
Ultimately you should be updating some underlying object with the values from the controller. In general, the slider belongs in the view layer - it's a display element. The action that adjusting the slider produces, however, is a component of the controller and it should fire back into your model to update a value. I highly recommend drawing boxes on a sheet of paper and trying to produce a clean a separation as possible for your application's layers - doing so in this case would produce two views for each "side" of the utility which would, via a controller, relate to a model. Then, the act of moving the slider would "instantly" update the model on the back. The Cocoa Fundamental video on the iPhone developer site demonstrates this to great effect.
I'm in exactly the same situation: first iphone app, new to mac programming, creating a utility, sliders on the flipside.
By following the example and the free tutorial here (http://www.bestechvideos.com/2008/11/13/writing-iphone-app-free-episode) I determined that the sliders and other controls should be declared on the flipsideviewcontroller. (Which leave the view pretty empty - I guess the use of the Nib resource file for the UI leaves the ...View.m class pretty much redundant?)
Wisequark's answer is a bit to general to help me though.
In terms of specifics:
- I can't find that video is there a link?
- Could we see some code showing the Controller-Model code?
- How do I persist the values set on the slider without having to build UI to go in the system settings?
(BTW is an Answer the right place to add to the question?)