Xamarin - Gradient background - xamarin

I'm trying to programmatically set a background gradient like this in Xamarin iOS:
CGColor[] colors = new CGColor[] { new UIColor(red: 0.05f, green:0.44f, blue:0.73f, alpha:1.0f).CGColor,
new UIColor(red: 45/255, green: 128 / 255, blue: 153 / 255, alpha: 0.01f ).CGColor};
CAGradientLayer gradientLayer = new CAGradientLayer();
gradientLayer.Frame = this.View.Bounds;
gradientLayer.Colors = colors;
this.View.Layer.AddSublayer(gradientLayer);
And it works, but I have form elements on the screen (labels, buttons, etc) and this is causing all of them to appear faded, as if the layer appears directly on top of the elements. I think this is what the code is doing - it's rendering the entire page, and then adding the layer with opacity on top of the screen (I want it behind it instead).
What I'd like, instead, is to have the background set as gradient, but any elements I add will not be faded and try to match the background colors.
I tried adding a view on top of the standard view, and setting the alpha to 1, background to white, but that didn't seem to help (suggesting my theory that programmatically it's adding a layer on top of everything after it's rendered).
What am I doing wrong?
Thanks!

I know I am late for the show but for future reference, I use:
this.View.Layer.InsertSublayer(gradientLayer, 0);
The 0 represents index.

Your gradient layer that is assign to the root View of the ViewController is being displayed "behind" all the other Views.
By default, views (UILabel, UIButton, etc) do not have a background color set and thus will blend with that background layer, if that is not the effect that you are looking for assign a background to them:
var button = new UIButton(UIButtonType.System);
button.Frame = new CGRect(40, 300, 120, 40);
button.SetTitle("No Background", UIControlState.Normal);
button.TintColor = UIColor.Red;
View.AddSubview(button);
var button2 = new UIButton(UIButtonType.System);
button2.Frame = new CGRect(180, 300, 100, 40);
button2.SetTitle("Background", UIControlState.Normal);
button2.TintColor = UIColor.Red;
button2.BackgroundColor = UIColor.White;
View.AddSubview(button2);

Related

Top part of a tableView specific color even if refreshing

I've run into a simple problem, that I can not solve even after looking everywhere..
I made a grey table view, and at the top I have a cell with white background.
Is it possible to whenever the user refreshes, make it also white (on the top)?
Try this code
let refresh = UIRefreshControl()
let backgroundColor = UIColor.red
refresh.backgroundColor = backgroundColor
refresh.addTarget(self, action: #selector(self.refreshs), for: .valueChanged)
tableView.addSubview(refresh)
var frame = tableView.bounds
frame.origin.y = -frame.size.height
let backgroundView = UIView(frame: frame)
backgroundView.autoresizingMask = .flexibleWidth
backgroundView.backgroundColor = backgroundColor // background color pull to refresh
tableView.insertSubview(backgroundView, at: 0)

How to merge two images in Xamarin Android and position it the same way like CGRect for iOS?

I successfully get out the two images in my resources folder in my project like this.
string BackGroundImage = "background_image";
string ObjectImage = "object_image";
var TheBackGroundImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(BackGroundImage, "drawable", PackageName));
var TheObjectImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(ObjectImage, "mipmap", PackageName));
What i have done after is very the tricky part comes in and I do not know how to quite get it right. What i try to do is create a new Bitmap where the BackgroundImage is the base. Then i create a canvas with my second image (ObjectImage) that is the image that will be on top of the BackgroundImage and try to merge it all together.
Bitmap Result = Bitmap.CreateBitmap(TheBackGroundImage.Width, TheBackGroundImage.Height, TheBackGroundImage.GetConfig());
Canvas canvas = new Canvas(Result);
canvas.DrawBitmap(ObjectImage, new Matrix(), null);
canvas.DrawBitmap(ObjectImage, 79, 79, null);
This does not work as anticipated, is canvas the way to go or is there somethinig else i should look at?
If we look at my iOS solution then i do it like this:
UIImage PhoneImage = UIImage.FromFile(PhonePath);
UIImage IconImage = UIImage.FromFile(IconPath);
UIImage ResultImage;
CGSize PhoneSize = PhoneImage.Size;
CGSize IconSize = IconImage.Size;
UIGraphics.BeginImageContextWithOptions(IconSize, false, IconImage.CurrentScale); //UIGraphics.BeginImageContextWithOptions(IconSize, false, IconImage.CurrentScale);
UIGraphics.BeginImageContext(PhoneSize);
CGRect Frame = (new CoreGraphics.CGRect(25, 29.5, 79, 79));
UIBezierPath RoundImageCorner = new UIBezierPath();
RoundImageCorner = UIBezierPath.FromRoundedRect(Frame, cornerRadius: 15);
PhoneImage.Draw(PhoneImage.AccessibilityActivationPoint);
RoundImageCorner.AddClip();
IconImage.Draw(Frame);
UIColor.LightGray.SetStroke();
RoundImageCorner.LineWidth = 2;
RoundImageCorner.Stroke();
ResultImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
var documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, "app.png");
NSData image = ResultImage.AsPNG();
And it works beautifully with a border around my second image as well.
How can i adjust my code to successfully merge two images together and position the second image preferably like a CGRect?
Try this:
public Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap)
{
Bitmap bitmap = backBitmap.Copy(Bitmap.Config.Argb8888, true);
Canvas canvas = new Canvas(bitmap);
Rect baseRect = new Rect(0, 0, backBitmap.Width, backBitmap.Height);
Rect frontRect = new Rect(0, 0, frontBitmap.Width, frontBitmap.Height);
canvas.DrawBitmap(frontBitmap, frontRect, baseRect, null);
return bitmap;
}
Update:
Here is the DrawBitmap method's introduce. I add annotations in the method.
public Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap)
{
Bitmap bitmap = backBitmap.Copy(Bitmap.Config.Argb8888, true);
Canvas canvas = new Canvas(bitmap);
//this Rect will decide which part of your frontBitmap will be drawn,
//(0,0,frontBitmap.Width, frontBitmap.Height) means that the whole of frontBitmap will be drawn,
//(0,0,frontBitmap.Width/2, frontBitmap.Height/2) means that the half of frontBitmap will be drawn.
Rect frontRect = new Rect(0, 0, frontBitmap.Width, frontBitmap.Height);
//this Rect will decide where the frontBitmap will be drawn on the backBitmap,
//(200, 200, 200+ frontBitmap.Width, 200+frontBitmap.Height) means that
//the fontBitmap will drawn into the Rect which left is 200, top is 200, and its width and
//height are your frontBitmap's width and height.
//I suggest the baseRect's width and height should be your fontBitmap's width and height,
//or, your fontBitmap will be stretched or shrunk.
Rect baseRect = new Rect(200, 200, 200+ frontBitmap.Width, 200+frontBitmap.Height);
canvas.DrawBitmap(frontBitmap, frontRect, baseRect, null);
return bitmap;
}

Set Background Image of a view with stretch to fit in Xamarin

I'm new with Xamarin. I'm actually trying to set the background image of a view and stretch it.
The image is a 2048x1536 pixels png.
nfloat vpHeight = View.Bounds.Height;
nfloat vpWidth = View.Bounds.Width;
Console.WriteLine(vpWidth);
Console.WriteLine(vpHeight);
The above code will return me 1024x768 (it's a landscape position).
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(img);
imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
var prevPage = new UIView()
{
Frame = new CoreGraphics.CGRect(0, 0, vpWidth, vpHeight)
};
prevPage.Add(imgView);
this is the code where I set the background, but the result is just the half of the image in x and y just like the image bellow:
So, how to make the image to adjust to the width and height of the view ?
ty !!
I would create an UIImageView as a background like so:
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(img);
imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
then add this to whatever view you are using.
ContentMode can be used like so:
Update
I would add it to the prevPage like so:
var prevPage = new UIView()
{
Frame = new CoreGraphics.CGRect(0, 0, vpWidth, vpHeight)
};
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(new CGRect(0,0,vpWidth,vpHeight));
imgView.Image = img;
imgView.ContentMode = UIViewContentMode.ScaleAspectFit; // or ScaleAspectFill
prevPage.Add(imgView);
Also its worth noting that using the View.Bounds to position the view is bit clunky. I would take a look into Autolayout as you will encounter problems on different devices and orientations. These are some good tutorials on Autolayout they might be native code but you are looking for the relationships of the views rather than the code.
Raywenderlich tutorial
Other Tutorial
Any probs with autolayout just ask another question.
I would recommend you stay away from FromPatternImage unless you are really using a pattern.
For the lowest memory consumption and best UI performance, this is what I do:
1st) Resize your image using an image context to match the size of the view:
UIGraphics.BeginImageContext(View.Frame.Size);
UIImage.FromBundle("bg.jpg").Draw(View.Bounds);
var bgImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
2nd) Display the resized image in a UIImageView and send it to the lowest Z-order:
var uiImageView = new UIImageView(View.Frame);
uiImageView.Image = bgImage;
View.AddSubview(uiImageView);
View.SendSubviewToBack(uiImageView);

Display Button With Text & Image In Xamarin IOS

I want to design a custom button in Xamarin IOS to display both Text and Image.
Please find the below image.
You can find the Text and down arrow symbol in the above image.
the down arrow symbol should always display after the text. The button text is dynamic.
Can any one suggest me to solve this.
You want to use the TitleEdgeInsets & ImageEdgeInsets properties of the UIButton to control where the inset of the text and image begins:
button.TitleEdgeInsets = new UIEdgeInsets(0, -button.ImageView.Frame.Size.Width, 0, button.ImageView.Frame.Size.Width);
button.ImageEdgeInsets = new UIEdgeInsets(0, button.TitleLabel.Frame.Size.Width, 0, -button.TitleLabel.Frame.Size.Width);
Full Example:
button = new UIButton(UIButtonType.System);
button.Frame = new CGRect(150, 20, 200, 50);
button.Layer.CornerRadius = 5;
button.BackgroundColor = UIColor.Black;
button.SetTitleColor(UIColor.White, UIControlState.Normal);
button.SetImage(UIImage.FromFile("ratingstar.png"), UIControlState.Normal);
button.SetTitle("StackOverflow", UIControlState.Normal);
button.TitleEdgeInsets = new UIEdgeInsets(0, -button.ImageView.Frame.Size.Width, 0, button.ImageView.Frame.Size.Width);
button.ImageEdgeInsets = new UIEdgeInsets(0, button.TitleLabel.Frame.Size.Width, 0, -button.TitleLabel.Frame.Size.Width);

HTML5 canvas, scale image after drawing it

I'm trying to scale an image that has already been draw into canvas.
This is the code:
var canvas = document.getElementById('splash-container');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// draw image at its original size
context.drawImage(imageObj, 0, 0);
};
imageObj.src = 'images/mine.jpeg';
// Now let's scale the image.
// something like...
imageObj.scale(0.3, 0.3);
How should I do?
You're thinking about it wrong. Once you've drawn the image onto the canvas it has no relationship to the imageObj object. Nothing you do to imageObj will affect what's already drawn. If you want to scale the image, do in the drawImage function:
drawImage(imgObj, 0, 0, imgObj.width * 0.3, imgObj.height * 0.3)
If you want to animate the scaling or are looking to achieve some other effect which requires you to draw the image at full size initially you'll have to first clear it before drawing the scaled down image.
What robertc says is correct, but if you really wanted to scale an image on a canvas after drawing it for some reason, you could just scale the whole canvas using the CSS width/height properties and that would scale the image without having to redraw it.

Resources