Stacking two ContainerViews? - uiviewcontroller

I have an UIViewController with its TableView view.
For the TableView header, I need to show 2 separate views, based on some flags.
I have 2 ContainerViews, each with its own embedding, two separate UIViewControllers. I was trying to show/hide the ContainerViews's view, based on the above mentioned flags.
The problem is that, the embedded views are not showing up like I expect them to. Here is my code:
//main `UIViewController` code; simplified
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"header_1"]) {
if(_shouldShowH1){
self.headerViewController = (HeaderViewController *)segue.destinationViewController;
[self.view bringSubviewToFront:self.headerViewController.view];
}
} else if ([segue.identifier isEqualToString:#"header_2"]){
if(_shouldShowH2){
self.headerViewController2 = (HeaderViewController2 *)segue.destinationViewController;
[self.view bringSubviewToFront:self.headerViewController2.view];
}
}
}
My problem is that, even if I call bringSubviewToFront:, I don't see the actual View.
Any suggestions?

I actually solved my issue following this post http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers with one minor modification: I don't need to swap the views, so I removed the functionality.
I decide beforehand which segue needs to be performed, so the decision branching is also removed.

Related

how to get context of views in view container in angular

In the following example, https://stackblitz.com/edit/angular-s8udwh
I have created EmbeddedViews in the ViewContainer. When creating the views, I pass a context object and when deleting the views, I use the context to find index of the view and delete it from the view container. This works fine.
I have added a button which when clicked should print the info of views currently in the container. I can find the length and views in the container using the APIs of ViewContainer but how do I get the context object from the views?
This is the function I am unable to write
printViewInfo(){
//I want to get all the views which are currently in the container and print their context objects.
let length = this.vc.length
for(let i=0;i<length;i++){
let view = this.vc.get(i);
//how to get the context back here from view??
}
}
What is the way to find context of views in a ViewContainer? I see that get returns a ViewRef and the ViewRef doesn't contain context. But ViewContainerRef doesn't provide APIs which return an EmbeddedViewRef
I got this working by typecasting the ViewRef into EmbeddedViewRef<any>. Is this the right way? My concern is that if a ViewContainerRef contains both EmbeddedView and ComponentView then how will I distinguish between them? Or would it be a wrong design to use both EmbeddedView and ComponentView in the same ViewContainer?
printViewInfo(){
//I want to get all the views which are currently in the container and print their context objects.
let length = this.vc.length
for(let i=0;i<length;i++){
let view = <EmbeddedViewRef<any>> this.vc.get(i);
//how to get the context back here from view??
console.log("view.context.option ",view.context.option.description);
}
}

Flash Builder (FlexPrintJob & PrintDataGrid) Chrome Shockwave error

I have an mx:application using the Flex 4.6.0 SDK and I’m having some issues with the FlexPrintJob in Chrome only. The FlexPrintJob worked fine in chrome, up until maybe a couple weeks ago (I made no changes to the code) and now I’ve started experiencing “Shockwave Crashes”.
While printing I’m using:
first title page template
middle section template to handle a DataGrid. This is using the PrintDataGrid and loops through the dataProvider to see if the data will fit on one page, if not it will create another.
Terms and conditions last page template
Problem: I’ve narrowed it down to this, I’m getting the Shockwave Crash error in chrome when the data (for the middle section) exceeds one page and tries to create another. This just started happening, I’m guessing with a chrome update…Sorry if I left something out and my description is lacking detail. I can add more clarification if needed.
Any ideas what’s going on?
Thanks!
--moe
public function doPrint(): void {
// Create a FlexPrintJob instance.
var printJob: FlexPrintJob = new FlexPrintJob();
// Start the print job.
if (printJob.start()) {
// Create a FormPrintView control as a child of the application.
var thePrintView: FormPrintView = new FormPrintView();
addElement(thePrintView);
// Set the print view properties.
thePrintView.width = printJob.pageWidth;
thePrintView.height = printJob.pageHeight;
thePrintView.horizontalAlign = "center";
// Set the data provider of the FormPrintView component's DataGrid to be the data provider of the displayed DataGrid.
thePrintView.summaryGrid.dataProvider = summaryGrid.dataProvider;
// Create a single-page image.
thePrintView.showPage("single");
// If the print image's DataGrid can hold all the data provider's rows, add the page to the print job.
if (!thePrintView.summaryGrid.validNextPage) {
printJob.printAsBitmap = false;
printJob.addObject(UIComponent(mainPagePrint), FlexPrintJobScaleType.MATCH_WIDTH);
printJob.addObject(thePrintView);
printJob.addObject(UIComponent(terms), FlexPrintJobScaleType.MATCH_WIDTH);
}
// Otherwise, the job requires multiple pages.
else {
// Create the first page and add it to the print job.
thePrintView.showPage("first");
printJob.printAsBitmap = false;
printJob.addObject(UIComponent(mainPagePrint), FlexPrintJobScaleType.MATCH_WIDTH);
printJob.addObject(thePrintView);
thePrintView.pageNumber++;
// Loop through the following code until all pages are queued.
while (true) {
// Move the next page of data to the top of the PrintDataGrid.
thePrintView.summaryGrid.nextPage();
printJob.printAsBitmap = false;
// Try creating a last page.
thePrintView.showPage("last");
// If the page holds the remaining data, or if the last page was completely filled by the last grid data, queue it for printing.
// Test if there is data for another PrintDataGrid page.
if (!thePrintView.summaryGrid.validNextPage) {
// This is the last page; queue it and exit the print loop.
printJob.addObject(thePrintView);
printJob.addObject(UIComponent(terms), FlexPrintJobScaleType.MATCH_WIDTH);
break;
} else // This is not the last page. Queue a middle page.
{
thePrintView.showPage("middle");
printJob.addObject(thePrintView);
thePrintView.pageNumber++;
}
}
}
// All pages are queued; remove the FormPrintView control to free memory.
removeElement(thePrintView);
}
// Send the job to the printer.
printJob.send();
}
I ended up taking things apart one-by-one and figured out what it was - the issue was is the FormPrintView. I had some unneeded properties in my PrintDataGrid that I think were originally copied from my main datagrid in my application.
I'm not sure why it was working before and just starting acting crashing now, but either way I shouldn't have had some of those properties there in the first place.
thanks!
--moe
<mx:PrintDataGrid id="summaryGrid" width="100%" height="100%" sizeToPage="true"
alternatingItemColors="[#f7f7f7, #ffffff]" alpha="0.8"
borderStyle="solid" borderThickness="1" color="#646262"
creationComplete="summaryGrid_creationCompleteHandler(event)" fontSize="9"
headerColors="[#ffffff, #e8e8e8]" headerHeight="25" paddingTop="5"
rowHeight="55" textAlign="center" wordWrap="true" paddingRight="-1" >

How to get object referece of UIPickerView when it create through html select tag

I have a UIWebview contains a html "select" tag, which is shown as a on the screen.
When I click the dropdown, the UIWebview brings up a UIWebSelectSinglePicker View automatically, which is shown as .
I want to change the picker view background color and text color. How can I achieve this goal?
I tried to listen on UIKeyboardWillShowNotification event, but at that moment, this view has not been created.
Thanks in advance for any helps.
I managed to resolve the issue myself.
If someone also want to change the UIPickView on the fly, please take a look:
First, add a listener on UIKeyboardWillShowNotification event.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(_pickerViewWillBeShown:) name:UIKeyboardWillShowNotification object:nil];
Second, when notification fired, call change background color method after delay. <-- This is very important, if call method without delay, the pickview does not exist at that moment.
- (void)_pickerViewWillBeShown:(NSNotification*)aNotification {
[self performSelector:#selector(_resetPickerViewBackgroundAfterDelay) withObject:nil afterDelay:0];
}
Third, go through the UIApplication windows and find out pickerView. And you can change what ever you want for pickerView.
-(void)_resetPickerViewBackgroundAfterDelay
{
UIPickerView *pickerView = nil;
for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
for (UIView *uiView in [uiWindow subviews]) {
pickerView = [self _findPickerView:uiView];
}
}
if (pickerView){
[pickerView setBackgroundColor:UIColorFromRGB(0x00FF00)];
}
}
(UIPickerView *) _findPickerView:(UIView *)uiView {
if ([uiView isKindOfClass:[UIPickerView class]] ){
return (UIPickerView*) uiView;
}
if ([uiView subviews].count > 0) {
for (UIView *subview in [uiView subviews]){
UIPickerView* view = [self _findPickerView:subview];
if (view)
return view;
}
}
return nil;
}
Hope it will help.
I believe I've come up with an alternate solution to this problem. There are certain circumstances with the other solution proposed where the label colours appear incorrect (using the system default instead of the overridden colour). This happens while scrolling the list of items.
In order to prevent this from happening, we can make use of method swizzling to fix the label colours at their source (rather than patching them after they're already created).
The UIWebSelectSinglePicker is shown (as you've stated) which implements the UIPickerViewDelegate protocol. This protocol takes care of providing the NSAttributedString instances which are shown in the picker view via the - (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component method. By swizzling the implementation with our own, we can override what the labels look like.
To do this, I defined a category on UIPickerView:
#implementation UIPickerView (LabelColourOverride)
- (NSAttributedString *)overridePickerView:(UIPickerView *)pickerView
attributedTitleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
// Get the original title
NSMutableAttributedString* title =
(NSMutableAttributedString*)[self overridePickerView:pickerView
attributedTitleForRow:row
forComponent:component];
// Modify any attributes you like. The following changes the text colour.
[title setAttributes:#{NSForegroundColorAttributeName : [UIColor redColor]}
range:NSMakeRange(0, title.length)];
// You can also conveniently change the background of the picker as well.
// Multiple calls to set backgroundColor doesn't seem to slow the use of
// the picker, but you could just as easily do a check before setting the
// colour to see if it's needed.
pickerView.backgroundColor = [UIColor yellowColor];
return title;
}
#end
Then using method swizzling (see this answer for reference) we swap the implementations:
[Swizzle swizzleClass:NSClassFromString(#"UIWebSelectSinglePicker")
method:#selector(pickerView:attributedTitleForRow:forComponent:)
forClass:[UIPickerView class]
method:#selector(overridePickerView:attributedTitleForRow:forComponent:)];
This is the Swizzle implementation I developed based off the link above.
#implementation Swizzle
+ (void)swizzleClass:(Class)originalClass
method:(SEL)originalSelector
forClass:(Class)overrideClass
method:(SEL)overrideSelector
{
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method overrideMethod = class_getInstanceMethod(overrideClass, overrideSelector);
if (class_addMethod(originalClass,
originalSelector,
method_getImplementation(overrideMethod),
method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(originalClass,
overrideSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, overrideMethod);
}
}
#end
The result of this is that when a label is requested, our override function is called, which calls the original function, which conveniently happens to return us a mutable NSAttributedString that we can modify in anyway we want. We could completely replace the return value if we wanted to and just keep the text. Find the list of attributes you can change here.
This solution allows you to globally change all the Picker views in the app with a single call removing the need to register notifications for every view controller where this code is needed (or defining a base class to do the same).

MediaWiki variant tabs

Anyone knows how to get the variant tabs to work as actual tabs and not as a drop down?
This is how sr.wikipedia.org has it:
and this is how I have it on my zablude.com/wiki/ page:
and I've tried everything I found and searched everywhere I could think of but I wasn't able to find a solution... anyone has any ideas how this works?
They hack it in JavaScript — see this piece of code at the bottom of Медијавики:Vector.js:
//to be able to switch the language variant (overrides the default buttons with more visible ones)
function tabWorkaround() {
if(mw.config.get('wgUserVariant') == 'sr') {
var tab_urls = {};
tab_urls[0] = document.getElementById('ca-varlang-0').getElementsByTagName('a')[0].href; //Ћирилица
tab_urls[1] = document.getElementById('ca-varlang-1').getElementsByTagName('a')[0].href; //Latinica
$('#p-variants').remove();
mw.util.addPortletLink('p-namespaces', tab_urls[0], 'Ћирилица');
mw.util.addPortletLink('p-namespaces', tab_urls[1], 'Latinica');
}
}
$(document).ready(tabWorkaround);
It would probably be cleaner to do it with a MediaWiki hook, though. The following code is untested, but should work if I haven't made any silly mistakes:
// show language variants as tabs in Vector skin
function tabWorkaround( &$skintemplate, &$links ) {
$links['namespaces'] += $links['variants'];
$links['variants'] = array();
return true;
}
$wgHooks['SkinTemplateNavigation::Universal'][] = 'tabWorkaround';
(In MW 1.17, this hook is only called from the Vector skin. In MW 1.18, it will affect all skins. If you don't want that, you could test whether $skintemplate->skinname == 'vector'.)
Try $wgVectorFeatures['collapsibletabs']['global'] = false;. That is intended for the dropdown on the other side, but might work for other dropdowns as well.

UISplitView with toolbar/tabbar at bottom of detail view

So here goes. I started with a standard out of the box splitview application for iPad. Root view left and detail view to the right. Detail view has it's toolbar at the top.
What I would like to add is a tab bar to the bottom of the detail view and have the tabs load in the details view, between the toolbar tabbar.
Here is the problem, do I add another view between them to load the tabs into, if so how do I get it resize and respect the toolbar and tabbar heights.
Clear?
Hope someone can point me in the right direction. Examples would be great, every example on the web seems to just be out of the box hello world style.
Yes the answer is really very simple. UITabBarControllers like SplitViewControllers were intended by Apple to only ever be the Root View Controller and hence you cannot nest a TabBarController in another view, but you can nest a UITabBar in a view, however.
I added the Tabbar to the details view at the bottom, a Navigation bar at the top and then a placeholder view between them. All in Interface Builder!, You will want to switch everything on with the autosize on the Placeholder view.
Next, Implement the UITabBarDelegate. For this you will need:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
from that you can use item.tag which if you give each item a unique tag in Interface Builder will let you know which tab the user clicked. I setup defined values for mine:
#define VIEW_TAB_A 0
#define VIEW_TAB_B 1
#define VIEW_TAB_C 2
Then you will then want to... well best I just let you see
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
[self switchToView:item];
}
- (void) switchToView : (UITabBarItem*) item {
if( currentViewController != nil ) {
[currentViewController viewWillDisappear:NO];
[currentViewController.view removeFromSuperview];
}
switch(item.tag) {
case VIEW_TAB_A:
currentViewController = self.viewA;
break;
case SCAN_VIEW_TAB_B:
currentViewController = self.viewB;
break;
case PROMOTIONS_VIEW_TAB_C:
currentViewController = self.viewC;
break;
}
UIView *aView = currentViewController.view;
aView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
aView.frame = placeholderView.frame;
[currentViewController viewWillAppear:NO];
[self.view insertSubview:aView aboveSubview:placeholderView];
if( currentViewController != nil ) {
[currentViewController viewDidDisappear:NO];
}
[currentViewController viewDidAppear:NO];
}
Remember to alloc the views (viewA, viewB, viewC) first in you viewDidLoad and obviously release in dealloc. Also take note of the autoresizingMask!
Hope this helps others.