iOS 9: Frame no longer set in viewWillAppear after UINavigationController pushViewController - uinavigationcontroller

I'm trying to solve a view placement bug that has arisen as of iOS 9. I am instantiating a view controller from a xib file (non-autolayout) and then pushing this onto my UINavigationController.
The problem is that when the view controller's viewWillAppear method is called, its frame has not yet been adjusted to the navigation controller's size and is still what was set in the xib file. It doesn't get set properly now until viewDidAppear.
This is completely screwing up my code. Does anyone know precisely what has changed that is causing this and what is the best way to handle it? I don't want to wait until viewDidAppear because this will look bad and make for a poor user experience.

I am also looking for the best fix.
My temporary one is to call the code that was in "viewDidAppear" in "viewDidLayoutSubviews". That way, my code will get called as soon as the frames are set.
But, make sure to add a boolean or something so that your code doesn't get called every time viewDidLayoutSubviews is called
-(void)viewDidLayoutSubviews{
if (didLayoutSubviews == NO){
didLayoutSubviews = YES;
// perform code that was in viewWillAppear
}
}

I occurred this issue too,
try to uncheck option "Resize View From NIB" from storyboard

Try moving the layout code from viewWillAppear to viewWillLayoutSubviews.

A little bit updated NickProvost's answer:
private var loadViewToken: dispatch_once_t = 0
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
dispatch_once(&loadViewToken) { [weak self] in
if let wSelf = self {
wSelf.setupView()
}
}
}

Related

Collapsing Toolbar Layout always expanded when returned from fragment

I have 2 fragments (Fragment A and Fragment B) both with collapsing toolbar layouts and corresponding recyclerviews within a coordinatorlayout.
If I scroll up in my recyclerview (so the CollapsingToolbarLayout has collapsed) and then open Fragment B from fragment A (Pushing A onto the backstack).
When I return to fragment A by hitting back. The CollapsingToolbarLayout/AppBarLayout is always expanded, even though the recycler view is in the same position.
Anyone experience this?
There's a issue related to this.
According to Chris Banes.
Add these lines inside onViewCreated() of your fragment to solve the issue.
ViewCompat.requestApplyInsets(mCoordinatorLayout);
It's an old question but none of the answers it's correct. I found this other question where they fixed the problem:
How to restore Collapsing Toolbar Layout State after screen orientation change
You have to set an id to your views in order to restore their state automatically.
I had face same problem so i write below code:-
private boolean isExpand = true;
private void setTitleNotExpand(boolean isExpand) {
if(getFragmentViewHolder() != null) {
this.isExpand = isExpand;
// AppBarLayout variable
getFragmentViewHolder().appbar.setExpanded(isExpand);
}
}
when you do add back stack then write below code :-
// write below code where you want to stick your toolbar
setTitleNotExpand(false);
// write below code where you want not to stick your toolbar
setTitleNotExpand(true);
on your onFragmentViewHolderCreated write below code :-
getFragmentViewHolder().appbar.setExpanded(isExpand);
another thing to consider is that views cannot restore their state if they don't have an id
Today, to fix this issue you only have to set an id to your coordinator layout to fix this.

How can I use Caliburn.Micro conventions to set a button's text and its action?

If I have a button in my View named, say, Save, then I can add a Save property to my ViewModel, and Caliburn.Micro will automatically bind it to my button's Content. For example:
public string Save { get { return StringResources.Save; } }
Or I can add a Save method to my ViewModel, and Caliburn.Micro will execute that method when the button is clicked. For example:
public void Save() {
Document.Save();
}
But what if I want to do both? C# doesn't let me declare a method and a property with the same name. Can I use conventions to both set the button's Content and the action to perform when it's clicked?
(I know I can manually bind one or the other, but I'd rather use conventions if it's practical.)
This is a common need, so you'd think it would be built into Caliburn.Micro, but it doesn't seem to be. I've seen some code that extends the conventions to support this (and I'll post it as an answer if nothing better comes along), but it's a workaround with some bizarre quirks -- so I'd like to hear if anyone else has made this work more cleanly.
Note: I did see this similar question, but it seems to be about whether this is a good idea or not; I'm asking about the mechanics. (I'll reserve judgment on whether it's a good idea until I've seen the mechanics. (grin))
Quick and dirty
<Button x:Name="Save"><TextBlock x:Name="SaveText"></TextBlock></Button>

iPad Split View App - DetailViewController Methods Never Called

I'm using a fresh iPad split-view template application in Xcode. I've added a sample data array and the data shows up just fine in the Popover view. However, when it's tapped, it doesn't call any methods from DetailViewController.m (setDetailItem in particular) like I'd expect it to.
Am I missing something here?
(I'm not sure what code I should post for this particular question, so I'll wait on you guys to ask for it.)
Thanks SO much in advance!
To troubleshoot this issue, you should check the method called didSelectRowAtIndexPath in the delegate for the table view. I remember that was called RootViewController by default and exists in the RootViewController.m file.
It should call the setDetailItem method. Check if it does so.
Posting the didSelectRowAtIndexPath method body here will help better.

AS3: Main stage listener for ProgressEvent?

Can I add a ProgressEvent listener to the stage?
I don't see it in any of the auto-complete options when I am typing in Flex.
What do people normally do to get a progress readout of the entire main runner's loading progress?
I try the following, which is where I would expect to see the ProgressEvent options pop up:
stage.addEventListener(
Thanks...
Try adding it to loaderInfo.
something like:
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
Also , if you're using the framework, you should probably extend the DownloadProgressBar.
I remember this old tutorial, but surely there must be plenty online.
I have a new problem:
I use the following code to show the progress of the download of my site content:
public function mainProgress(e:ProgressEvent):void
{
var w:Number = e.bytesLoaded / e.bytesTotal;
_mainprog.graphics.clear();
_mainprog.graphics.beginFill(0x000000);
_mainprog.graphics.drawRect(0, 0, w * stage.stageWidth, 50);
_mainprog.graphics.endFill();
}
But it doesn't seem to work.
What happens is that the loaderInfo object thinks that the site has loaded before I am actually ready to display anything. So what ends up happening (I think) is the site loads, the loader progress disappears before the initial page's graphics have fully loaded, and then there is a delay between when the completion of the loaderInfo object happens and the actual graphics appearing.
Has anyone else had this problem before?
Thanks...

How print Flex components in FireFox3?

Thanks to FireFox's buggy implementation of ActiveX components (it really should take an image of them when printing) Flex components (in our case charts) don't print in FX.
They print fine in IE7, even IE6.
We need these charts to print, but they also have dynamic content. I don't really want to draw them again as images when the user prints - the Flex component should do it.
We've found a potential workaround, but unfortunately it doesn't work in FireFox3 (in FireFox2 it sort-of works, but not well enough).
Anyone know a workaround?
Using the ACPrintManager I was able to get firefox 3 to print perfectly!
The one thing I had to add to the example was to check if stage was null, and callLater if the stage was null.
private function initPrint():void {
//if we don't have a stage, wait until the next frame and try again
if ( stage == null ) {
callLater(initPrint);
return;
}
PrintManager.init(stage);
var data:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
data.draw(myDataGrid);
PrintManager.setPrintableContent(data);
}
Thanks. A load of callLater-s added to our custom chart code seems to have done it.

Resources