calling presentModalViewController to show a view created programmatically - uiviewcontroller

I've noticed that if I create a UIViewController-derived class programatically (without using a nib) to be displayed with a call to presentModalViewController, as the view slides in, it's actually transparent by default until the view covers the entire screen, after which point the 'opaqueness' seems to kick in and the view beneath the modalview is no longer visible.
If I create the view using a nib, it slides in as you'd expect, fully covering any views beneath with no transparency issues.
I noticed that the Apple examples tend to use a nib-based view for ModalViews, but wondered why. Perhaps I'm missing something.....

It was down to a foolish coding error on my part.
I realised I'd copied/pasted some code from elsewhere into my ViewDidLoad
self.view.backgroundColor = [UIColor colorWithRed:0.6 green:0.4 blue:0.2 alpha:0.3];
I'd set a value of 0.3 for alpha.
Set it to 1.0 and transparency issue goes away...
Problem solved

Related

Changing materials in Forge

We are currently making the client retrieve the object states when the page loads (which will cause the 'pending' objects in the model to turn into different colors). Then we poll for changes to update the coloring (Firstly: pending object gets colored when the viewer loads, and then we keep polling to check and change state again, to make Forge render those in a different color and store their old color/material. When the polling received a change that an object should no longer be colored, it tells Forge to use the old color/material again.
The problem:
We've found out what the problem is, but we couldn't find out how to fix it. The problem is that changing materials in Forge doesn't work after startup anymore, it only works in the first ~3 seconds or so (the materials were used to show the colors).
However, setting overlays works even after the first ~3 seconds, (showing overlays instead of materials to show the colors).
This is not what we want to achieve. This looks unoptimized, because overlays will be shown through everything.
The materials, however, seem to be 'locked', as in, they cannot be changed anymore after the first ~3 seconds. It seems like they aren't refreshed or something
In the examples, we found they used viewer.impl.invalidate(true) to refresh the Forge viewer, but that doesn't do anything after ~3 seconds.
We've also tried every combination of viewer.impl.invalidate(true, true, true) as well as setting material.needsUpdate to true, as well as trying to re-render the entire scene.
We also found this: https://github.com/mrdoob/three.js/issues/790, but we couldn't find a good way to do that in Forge, we tried viewer.requestSilentRender() but that didn't do anything either.
Anyway, we've tried everything we could come up with and could find online to make the materials work, but nothing made a difference.
We are looking to find someone that's more experienced with how Forge works that can see what the material code is doing wrong.
As for the content, here is all the code you will need to understand what is happening:
DROPBOX LINK
And here is a small part of the "index.html" file that sets the color:
try
{
viewer.restoreAllColorOverlays(); //for materials instead of overlays: viewer.restoreAllColorMaterials();
$.each(colors, function(color, selectionIds)
{
viewer.setColorOverlay(selectionIds, color); //for materials instead of overlays: viewer.setColorMaterial(selectionIds, color);
});
}
catch(error)
{
console.error(error);
}
I have no idea how you implement your app, so I only tell what I found in your codes. If you want to resolve the issue you addressed, you can consider providing a reproducible case demonstrating that, I will gladly pass it to our dev team. Those following items should be in the reproducible case:
A short exact description of what you are trying to achieve. The behavior you observe versus what you expect, and why this is a problem.
A complete yet minimal sample source model to run a test in.
A complete yet minimal Forge app that can be run and debugged with a simple procedure to analyze its behavior lives in the sample model.
A complete yet minimal pure three.js app that can be run and demonstrated the shader effect you want. Note. Forge Viewer is using r71 three.js.
Detailed step-by-step instructions for reproducing the issue, e.g. which element to pick, what command to launch etc.
If your reproducible case could not be posted here publicly, please send it to the forge.help#autodesk.com and remove sensitive data or information before you send.
=== Something I found in your codes:
I found here are some wrong types and missing actions in your ColorMaterial extension. The color property of an material should the a type of the THREE.Color. Here is my modification:
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color)
{
if( !(color instanceof THREE.Color) ) throw 'Invalid argument: Color';
var material = new THREE.MeshPhongMaterial
({
color: color,
opacity: 0.8,
transparent: true
});
viewer.impl.matman().addMaterial( 'ColorMaterial-' + new Date().getTime(), material, true );
// ...........
};
Its' result is here:
In the ColorOverlay extension, The type of material color property is also wrong, it should be a type of THREE.Color, too. Changing it into THREE.Color should work fine. In addition, overlay is covers on 3D objects, so you should call viewer.hide() with your setColorOverlay() together. Otherwise, it won't look like a transparent object.
Without hidding 3D object of the wall:
hide 3D object of the wall:

UIViewcontroller keeps portrait coordinates when in landscape mode

I have an app that is designed to start up in Landscape mode, this all works fine. I add an imageview to cover the screen and then add a scrollview halfway down. Again all works fine.
I then add a series of uiimageviews again all fine. I notice if i try to click the far right image there is no response but the other images preceding this work fine. With lots of digging around I discovered the viewcontroller keep portrait coordinates. I have a tabbar at the bottom when I click to go to another view and then go back to the main view the far right uiimageview not works. Has anyone seen this before? I am guessing the view is redrawing itself when it comes back?
You should use .bounds property instead of the .frame property of the view.
Bounds honor the UIVIew's coordinate system.
It's well explained in this answer: https://stackoverflow.com/a/8181113/402223
See this article which answered my question here
- (void)viewDidLayoutSubviews
{
// fix for iOS7 bug in UITabBarController
self.selectedViewController.view.superview.frame = self.view.bounds;
}
note don't add it to viewdidload method.
Thanks Martijn you put me on the right track.

iPhone - How do I make viewControllers landscape?

I have a uiNavigationController and two viewControllers. The problem I am having is the views are being generated in portrait size even though I want them in landscape!
Here is what I am doing:
1) Creating an instance of view1 and adding it to the uiNavigationControllers stack. This is performed inside the applications delegate didFinishLoadingWithOptions(...) method.
2) view1 has a button that when clicked creates an instance of view2 and pushes it onto the uiNavigationControllers stack.
This appears to work fine apart from the fact the views are being created in portrait format. I was going to manually force landscape by using transform methods once I create their instance but this feels really hacky.
I did speculate that this has something to do with the "shouldAutorotateToInterfaceOrientation" method, but this is set for landscape in all viewControllers.
I am royally confused.
Question 1) How on earth do I solve this, is the 'hacky transform' approach the only way?
Question 2) Is this the correct way to be using a navigationController - I am new to iPhone programming. All I want are two landscape views that I can click between and this seems to do this aside from the landscape bit ^^.
I found the answer for this problem.
The navigation controller DOES inherit the shouldAuthororateToInterfaceOrierntation method for each of the views inside its stack, I however made a mistake :)
After adding the navController to the main window I had not deleted the part where by default it adds the a rootController view to the main window. There was some kind of conflict which stopped my navigation controller working as expecting - removing that line fixed everything.

UIViewController workflow management without modal, tabbar and navigationcontroller?

Hello stackoverflow fellows!
Please consider an UI workflow in iOS:
One main viewcontroller and several other viewcontrollers branching out from there:
mainviewcontroller
+-viewcontroller 1
+-viewcontroller 2
+-viewcontroller 3
etc.
I would like to be able to switch and switch back from the main viewcontroller to one of the other viewcontrollers AND also switch BETWEEN the other viewcontrollers.
All iOS patterns I know of seem to be problematic for that usecase:
UITabbarController would be the right choice if I could make the
tabbar disappear - it doesn't fit to the design. I was able to hide
the bar, but the viewcontroller screens don't resize themselves and
the whole thing feels hackish.
UINavigationController is designed for a sequential order of
screens, also the slide-in animation doesn't fit to the design
Modal viewcontrollers are also meant for a sequential order, additionally I have to keep
track of how many viewcontrollers are on the stack. Also, there is a
timing problem with dismissing a view controller and immediately
presenting the next one.
I could just switching views within a viewcontroller I guess, but the
viewcontrollers have all kinds of subtasks to do. I would end up with
one huge viewcontroller and lots of methods embedded for the
different views.
My question:
What would be the best approach to manage a bunch of viewcontrollers in any order I would like to?
Thanks for any help!
I would have a main UIViewController. That one would have references to the other three UIViewControllers. You can then do something like this from inside your main UIViewController:
[self.view addSubview:view1.view];
This works, but I wouldn't advise you doing because it's not the natural way of doing it. As stated by apple:
You should not use view controllers to manage views that fill only a
part of their window—that is, only part of the area defined by the
application content rectangle. If you want to have an interface
composed of several smaller views, embed them all in a single root
view and manage that view with your view controller.
Ok, my solution is not perfect, but seems to work:
Create a UINavigationController.
Use the viewcontrollers: method to add a stack of viewcontrollers to your liking.
When switching between viewcontrollers, rebuild the stack and attach again.
Problem: You only have the navigation controllers animation (slide in/out) at your disposal.
But you can disable the navigationcontrollers animation, get the next viewcontrollers view, animate that in with a UIView animation, then switch to the view controller itself through stack building as explained above.
Really far from perfect, but works.

Xcode: iAds in 5 ViewControllers: How?

Problem: I can't get one instance of iAds to be viewed in 5 viewcontrollers.
I used the iAdSuite example from dev.apple.com to integrate iAds into my app. All is fine until one uses the back button to go back a page within the NavControllerstack. The Ad doesnt reintegrate into the view.
One logical approach seemed to me to load up one instance of the adbannerview into my main window in my AppDelegate:
[self.window addSubview:MainView];
[self.MainView addSubview:NavController.view];
[self.window makeKeyAndVisible];
MainView takes the full window but is set to stretch up when the adbanner is loaded.
I seem to be doing something wrong because the navcontroller view seems to always take up the entire screen.
Question: How can I succesfully implement iAds in my rootview? (Or succesfully migrate iads around)
Could you keep a global reference to the iAd Banner and call [adBanner.view removeFromSuperView] followed by [theViewThatYouWantToDisplayAdOn addSubview:adBanner.view]