Image doesn't load inside a frame - forms

I have an app where I load an Image inside a Frame on a ViewCell. On Windows Phone 8.1 the image doesn't show the first time the page is shown, but if I navigate to another page and then return, it loads. Android and iOS work fine.
The problem is the Frame, because if I set the Image as the ViewCell's Content, it loads normally.
View = new Frame {
Content = new Image {
Source = "img.png"
}
};
Debugging I found out that both the Width and Height of the Image are -1. MinimiumWidthRequest and MinimumHeightRequest have no effect. I also tried using the FFImageLoading library, to no avail.
I use the frame so I can put a black border on it using a custom renderer.
Any help would be much appreciated.

You can use StackLayout instead of Frame:
View = new StackLayout {
Children = new Image {
Source = "img.png"
}};

Related

PKAddPassButton not showing icon at all

Why PKAddPassButton isn't showing icon?
This happens in both cases when button is single line expanding to entire stack view width
and when it is double line inside UIView container with centreX constraint.
Setting frame or width doesn't change anything.
private lazy var addPassButton = UIViewFactory.create.container().apply {
let button = PKAddPassButton()
$0.addSubview(button)
button.snp.makeConstraints { make in
make.top.bottom.equalToSuperview().inset(16.0)
make.centerX.equalToSuperview()
}
}
On real device all works correctly. Icon not showing only on simulator.

Changing Label/Button Text colour dynamically based on the dynamically changing background

I know it may sound a little bit of a drag to ask this question but I am curious if anything like this is available.
I am building a app in which the background image (covers full view with a blur effect) of each view controller changes dynamically. This background image will be in all the view controllers, each one having a different set of UIControls (Labels, Buttons, Table Views, Collection Views, containers, tabs, etc).
Sometimes when the background image is very light, the foreground texts (labels, buttons) with white text colour are not visible at all. Also the vice versa is a problem too.
So I would like to know if there is any way to change the foreground text colour dynamically based on its background.
Recently I faced the same problem, And I think what you looking for is either image is bright or dark so that you can set property accordingly Hope this will help.
Create observer, everytime image change it will check if its a dark image or bright and based on that will call the function UIForDarkImage and UIForBrightImage
//ImageView observer to observe the image change and perform the UI action based on the image colour
//Your imageView you are using to set image
var imageView: UIImageView {
didSet {
if imageView.isDark(image.bounds) { //dont pass the full image bounds pass the rect where your buttons or label places it will save your hell lot of time
setUIForDarkImage() // here you set buttons and labels color to white or whatever changes you want to perform based dark image
}
else {
setUIForBrightImage() // here you set buttons and labels color to black or whatever changes you want to perform based bright image
}
}
}
UIImageViewExtension for checking if Image is a dark image or bright Image.
What happening is, It will go through image pixel-by-pixel and check if the pixel is bright or dark and if we get dark pixels more than the threshold we have set, we will assuming that its a dark image else it's a bright image.
PS: For better efficiency not checking the whole image (for a high-resolution image it will slow down if we will check all pixels) so only checking the part of the image in which we need our button or label, you can set rect based on your requirement. And also scaling by 0.45 to check few pixels in that rect(you can increase or decrease for more/less accuracy).
extension UIImageView {
func isDark(_ rect:CGRect)->Bool {
let s=image?.cgImage?.cropping(to: rect);
let data=s?.dataProvider?.data;
if data == nil {return false;}
guard let ptr = CFDataGetBytePtr(data) else {return false;}
let threshold = Int(Double(rect.width * rect.height) * 0.45);
var dark = 0,len=CFDataGetLength(data);
for i in stride(from: 0, to: len, by: 4) {
let r = ptr[i], g = ptr[i+1], b = ptr[i+2];
if (0.299 * Double(r) + 0.587 * Double(g) + 0.114 * Double(b)) < 100 {dark += 1;}
if dark > threshold {return true;}
}
return false;
}
}
PS: If you also like to know what I am doing in setUIForBrightImage() and setUIForDarkImage do let me know
Here's what I would do: Create a struct that contains the name of the image view and a tint color to use for your labels, buttons, etc.
Add a property to your view controllers using this new struct. Let's call it backgroundImageSettings.
Add a didSet method to the property that calls another method useBackgroundImageSettings() that installs the image into the background of the view controller's content view, sets the tint color for the view controller's content view, and calls setNeedsDisplay() on the content view.. Also call useBackgroundImageSettings() in your viewDidLoad so that setting your backgroundImageSettings still works even if you view controller's view hasn't been loaded yet.
I like Duncan's answer! An additional step you can take is to set a slight overlay onto your background image.
For example, if you have a background image with really dark colors and you can't see your black text very well, then you can add a layer with a background color of white and an opacity less than 1. That way there's a bit of white to make your text more readable, and you can still see the background image.
let overlay = UIView(frame: yourSuperView.bounds)
overlay.backgroundColor = UIColor.white
overlay.layer.opacity = 0.5
yourSuperView.addSubview(overlay)

Swift shrink UIImageView according to what image it contains

I have an UIImageView which is as big as the whole view. When I insert an image, I would like for the image view to shrink itself in order for it to be as big as the image I insert itself. I cannot find a way to do it.
There are a number of ways you can approach this assuming you have a UIImageView declared like so:
#IBOutlet var dynamicImageView: UIImageView!
When changing your image, set the imageView size to that of the UIImage e.g:
func changeImage(){
if let image = UIImage(named: "Octocat"){
dynamicImageView.image = image
dynamicImageView.frame.size = image.size
print("Size Of ImageView = \(dynamicImageView.frame.size)")
}
}
Just use the .sizeToFit method e.g:
func changeImageAgain(){
if let image = UIImage(named: "Octocat"){
dynamicImageView.image = image
dynamicImageView.sizeToFit()
print("Size Of ImageView = \(dynamicImageView.frame.size)")
}
}
Running on an iPhone 7 Plus the UIImageView size is initially (375,647), and when applying either method the size changes to (800,665) which is the same size as the GitHub OctoCat:
I have created one demo app which will contains XIB with image view. Here I have written code to resize imageView as per image size. This code is working in my project, I shared link for demo app, you can download and test it.
In this project, I have implemented code to create imageView based on image size and vertically and horizontally centred aligned.
Also implemented code to zoom image.
https://app.box.com/s/sro2g7gdv5c67f9oj97gfhicjnpo2vqc
I hope this will work for you and as per your requirement.

How to Make NSVisualEffectView That Only Appears When Content is Beneath It

I am working on a macOS application that makes use of NSVisualEffectView to achieve transparency. I want to achieve an effect similar to that of iOS' Cover Sheet widget view. Notice how when you scroll up, content a blur appears around the search bar. I want do this in a macOS app so that when content in a table view is scrolled beneath a certain point an NSVisualEffectView blurs it. How would I do this? Thanks in advance.
Create a instance of Visual Effect View as following and set on window:
func setVisualEffectToWindow(window: NSWindow) {
// create the visual effect view
var blurryView = NSVisualEffectView(frame: NSRect(x: 0, y: 0, width: 800, height: 600)) //Create with size you want or you can use window content bound here
// this is default value but is here for clarity
blurryView.blendingMode = NSVisualEffectBlendingMode.BehindWindow
// set the background to always be the dark blur
blurryView.material = NSVisualEffectMaterial.Dark
// set it to always be blurry regardless of window state
blurryView.state = NSVisualEffectState.Active
window.contentView.addSubview(blurryView)
}

Playground, unable to set same UIImageView to more than one UIView

I've got this code
override public func viewDidLoad() {
let imageBlankCard = UIImage(named: "BlankCard.png")
let imageViewBlankCard = UIImageView(image: imageBlankCard)
rockCard.addSubview(imageViewBlankCard)
scissorCard.addSubview(imageViewBlankCard)
paperCard.addSubview(imageViewBlankCard)
self.view.addSubview(rockCard)
self.view.addSubview(scissorCard)
self.view.addSubview(paperCard)
}
But when I run the playground, only the latest UIView (paperCard) is displayed properly, the other cards are not shown at all as you can see in the image here: there should be two cards like the last one, in place of the arrows.
Can someone help me? Thanks everybody!
According to the documentation,
Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.
This explains the behaviour that you're getting.
One solution to this is to create three separate image views and add each of them as a subview.
Judging by the variable names, I think you are creating something similar to a rock paper scissors game. And you have three views that each holds an image view with the image of a blank card. And you want to add the image of a stone, paper and scissors as an overlay to the image view. If that's what you want to do, why not just make rockCard, paperCard and scissorsCard themselves UIImageViews and set the image to be BalnkCard.png?
let imageBlankCard = UIImage(named: "BlankCard.png")
rockCard.image = imageBlankCard
scissorsCard.image = imageBlankCard
paperCard.image = imageBlankCard