Not able to set status bar background in Xamarin.iOS - xamarin.ios

I need to change status bar UI, where background is black and text colour is white, in Xamarin.iOS (not forms).
For that I wanted to customise the status bar view, in have searched all I could on the internet and found below code working for majority of the people.
var statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
//tried with key statusBarWindow.statusBar as well.
statusBar.BackgroundColor = ...;
Above code crashes in Xamarin.iOS (tested on iPhone Xs Simulator).
Here is the log of the crash.
at (wrapper managed-to-native) ObjCRuntime.Messaging.xamarin_IntPtr_objc_msgSend_IntPtr(intptr,intptr,intptr)
at Foundation.NSObject.ValueForKey (Foundation.NSString key) [0x0001c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.2.1.12/src/Xamarin.iOS/Foundation/NSObject.g.cs:599
Could anyone help me with any hint as to why this code crashes in Xamarin.
I tried finding the cause on this GitHub thread https://github.com/mono/Embeddinator-4000/issues/597
But here also I am not able to get any clue of it.
Also, if there is any other way to customise the status bar I would like to drop this idea and go ahead with proposed one.

From what I know this works but usually when I use this I always make a check if the selector is available or not using RespondsToSelector:
UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
{
statusBar.BackgroundColor = UIColor.White;
}
Also, do not forget to add the style to info.plist
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleBlackOpaque</string>
Update
Use the above code in AppDelegate.cs in the FinishedLaunching method.

Related

How to fix UICollectionView - All cells disappear - Xamarin ios

I am using a UICollectionView in C# Xamarin ios and sometimes all of the cells will disappear from the screen. This happens normally on a scroll and I have to re-invoke the view that my UICollection View is on.
I can't show my exact code as this is a project that I am working on but the initialization basics look a little like this:
Bounds screenBounds = screen.Bounds
UICollectionViewFlowLayout layout = new UICollectionViewFlowLayout();
UICollectionView collectionView = new UICollectionView(layout, bounds)
I initialize a few other things like source and register cell and also add separation and border styles.
I have been also getting an error about a view not being in the hierarchy don't know if this has anything to do with it.
I do return the collectionView at the end and will add this returned value to my template which has a scroll view in which I add the UICollectionView to.
May I also mention I don't use any of the StoryBoard and am using a DuqueReusable cell in my collection view source.
I have been stuck on this for ages so thank you in advance for anyone who can give me any sort of tips or answers to this question.
Insure you make any changes to ItemsSource or to cells data on UI thread only, otherwise you might obtains an uncatchanble async crash and you'll end up with an empty view.
Device.BeginInvokeOnMainThread(() => {
// do your stuff
});

How do you use a storyboard reference in a Tab Bar Controller with Visual Studio?

I have a view controller in one storyboard that I'd like to reuse in another storyboard's Tab Bar Controller. In XCode, I can add a storyboard reference and then ctrl-drag from the Tab Bar Controller to it, and it shows up as another tab, just like a View Controller would in the same storyboard. I'm trying to do this in VS 2017 though and it doesn't seem to work. Or if it does, I'm unsure of how to do it. I tried adding a storyboard reference and ctrl-dragging, just like I do for normal View Controllers. I select "Tab" under "View Relationship" which pops up when I finish dragging, but it never makes the link and never makes the tab.
Is this even something that is valid? And if it is, is it a bug/limitation with VS that I can't do this, and is there a workaround?
Edit:
I managed to get this to work programmatically. Here's what I did in case anyone wants to know. However, I still would like to know the answer to my previous questions.
First, in your desired VC (I'm going to call it TestVC), make sure you add a Tab Bar Item (not a tab bar). Set up the title and image as you would normally. Then, in your Tab Bar Controller's ViewDidLoad method, do something like this:
var storyboard = UIStoryboard.FromName("StoryboardNameTestVCIsIn", null);
var vc = storyboard.InstantiateViewController("TestVC");
var existing = new List<UIViewController>(ViewControllers);
existing.Add(vc);
ViewControllers = existing.ToArray();
Is this even something that is valid? And if it is, is it a bug/limitation with VS that I can't do this, and is there a workaround?
It is not support to add Tab relationship by this way. As you mentioned above, you could only implement that programmatically. Maybe in the near future Xamarin will support it like in Xcode.
Click on the segue , and you can see all the actions you can do.

Android UI alignment issues when supporting kitkat

I have been struggling to find a reliable solution to solve an issue from the past two weeks.
In our android app, we make use of a back ground image. There are some borders in this image in which we have to place different views.
The application needs to be supported from 4.0 to current latest version.
The issues I am facing are listed below.
The app when installed on devices with navigation bar looks perfect, but when run on devices without navigation bar the alignment is disturbed.
What did I try?
I tried checking if the OS version is 18 (4.3) and according to that created two layouts for each activity and installed.
The code is here
if (DEVICE_API_VERSION > 17) {
setContentView(R.layout.layoutwithnavigationbar);
} else {
setContentView(R.layout.layoutnonavigationbar);
}
But there are devices like samsung galaxy note II, which are upgradable to 4.4.2 and have no navigation bar.
Then I tried out the following proceedure.
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
boolean hasMenuKey = ViewConfiguration.get(mContext).hasPermanentMenuKey();
System.out.println("has back key . . . . "+hasBackKey);
System.out.println("has home key . . . . "+hasHomeKey);
System.out.println("has menu key . . . . " + hasMenuKey);
if(hasHomeKey || hasBackKey) {
setContentView(R.layout.layoutnonavigationbar);
} else {
setContentView(R.layout.layoutwithnavigationbar);
}
But again I had no luck.
In sony xperia sl which is 4.1.2 version of android, xhdpi, no navigation bar picks the layout perfectly, but in sony xperia m2, returns hasBackKey as true even if it is having a navigation bar and has no hardware menu buttons, and picks up layout with no navigation bar and layout looks ugly. Even tried few more things like resource id of navigation bar but in htc one s which has hardware buttons and no navigation bar, has a resource id for navigation bar. so it didn't work. I got the resource id as shown below.
int resourceId = resources.getIdentifier("navigation_bar_height",
"dimen", "android");
Did anyone have this problem?
Am I doing any thing silly or missing any thing?
What I am looking for?
1) My app should work from 4.0 to latest version.
2) If any device got navigation bar it can either be made completely transparent and use screen below that too, so that UI is not affected or any other better solution is also fine.
3) Want to know if there is any standard way to know if the device has a navigation bar or uses hardware buttons?
4) How can I make the navigation bar transparent in devices prior to Kitkat.
Note : App only is in landscape mode. Even tried transparent Navigation bar themes but they are only supported in kitkat. I am using values-hdpi,values-xhdpi, ect to get the UI aligned in different devices.
Please help me find a solution.
Finally after a lot of research I could not find a reliable solution. I don't know if it is the standard way of doing but it served my purpose. I used the answer in the stackoverflow question. get real size of screen
Got the display size of the screen as well using the following
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int displayHeight = displayMetrics.heightPixels;
int displayWidth = displayMetrics.widthPixels;
if real width and display width are same it means device does not have a navigation bar, else device has a navigation bar. Accordingly I am setting appropriate layouts. I am concerned only with width as my app only runs in landscape mode.

How to set background image for Dialog?

I am trying to do this:
public class DialogMenuHawaii extends Dialog {
Style s = UiFactory.getBaseStyle();
s.setBgTransparency(0);
s.setBgImage( <my image >);
this.setUnselectedStyle(s);
}
but it doesn't work.
First, I suggest you use a theme. We constantly change small implementation details e.g. customizations like the one you are doing will not be portable between LWUIT 1.4 and 1.5. There is no reason whatsoever not to use a theme for something like this.
If you are interested in the pain and suffering of manually coding view logic into your application you can use several methods such as getDialogComponent() to get the style from them and manipulate that. Dialog is a complex beast due to the fact that its really a form padded away from the edges.
Open your '.res' file in resource Editor and select your preferred theme,
Under 'Unselected' tab open the DialogContentPane style, if you don't have one create it look at the end of this answer on HOW TO DO IT?, and set the background image to the image you need to show as Dialog bg
Under 'Unselected' tab open the DialogBody style, if you don't have one create it look at the end of this answer on HOW TO DO IT?, and set the background transparency as '0' and also make sure the background image type is NONE
NOTE: The above code will reflect for all the Dialogs in your application. If you want a particular dialog with background image than derive new styles from these default styles, and follow the above steps to apply it to your DialogMenuHawaii or any runtime Dialogs.
HOW TO: I would recommend you to go through the Shai's blog posts LWUIT Resource Editor Tutorial Part 1 till part 10. To better understand the Resouce Editor its features and capabilities.
:
:
:
PS: Programmatic-ally i haven't been able to achieve it using TextArea which is the case for default Dialog's. If you replace the dialog body component with Label if works fine, the code sample is given below. I haven't delved much into why is it so ? maybe will do it in my free time. Hence i have proposed a working alternative solution which is scripted above using Resource Editor and below using the code
class MyDialog extends Dialog {
public void show() {
Container octnPane = this.getDialogComponent();
octnPane.getUnselectedStyle().setBgTransparency(0, false);
Container ctnPane = (Container)((BorderLayout)octnPane.getLayout()).getCenter();
ctnPane.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED, false);
ctnPane.getUnselectedStyle().setBgImage(myImage, false);
Label t = new Label("Dialog");
t.setUIID("DialogBody");
t.getUnselectedStyle().setBgTransparency(0, false);
ctnPane.addComponent(t);
super.show();
}
}
This is for Dialog background.
Dialog dialog = new Dialog();
dialog.getDialogStyle().setBgImage(Image.createImage("/image/image.png"));
If you want to set transparency of Dialog with image.
dialog.getStyle().setBgImage(Image.createImage("/image/image.png");

Customising the title bar in Java ME

Is it possible to customise the title bar in Java ME?
You might like to check out J2ME Polish, which provides a massive amount of UI customisation for MIDlets, including the title bar: link text
The API doesn't provide functionality for customising the default title bar, but we can attempt to write our own bar. This is in itself a minor breach of UI conventions. Some phones allow us to use setTitle(null) to remove the title. The phones in the Java mobile toolkit behave this way, but the Series 40 and 60 emulators don't seem to support this and instead generates a default title. On the other hand, the Sony Ericssons and Motorolas I've tested seem to support this.
However, we can detect whether the ability to remove the titlebar is present. We do not use the sizeChanged callback as the calling of this function may be delayed when the canvas is not visible. Instead we call getHeight both before and after removing the bar. According to the spec, getHeight should always return the correct and up to date value, even when the canvas is not being displayed. Here is code for implementing the detection:
public static boolean HIDE_TITLE_ENABLED;//Whether the implementation allows us to hide the title bar
static{
//See if we can remove the title by ensuring it is non-nil, then attempting
//to remove it. If we can't, then reset it.
Canvas c=new Canvas(){
protected void paint(Graphics g){
}
};
c.setTitle("test");
int preHeight=c.getHeight();
c.setTitle(null);
int afterHeight=c.getHeight();
HIDE_TITLE_ENABLED=preHeight!=afterHeight;
}
It is also possible to hide the title bar using full screen mode, but this hides other elements as well. This method is popular in games.

Resources