I am displaying a custom UIView. There is a variable 'hideLogo' which when set to false should hide the Logo image when the view appears. However the logo is only hidden once the subview is re-added.
How can I make the image hidden when the view is added first time.
class MenuBar: UIView {
#IBOutlet var LogoImage: UIImageView!
static var showLogo: Bool?
override func awakeFromNib() {
super.awakeFromNib()
if(MenuBar.showLogo == false){
self.LogoImage.isHidden = true
}
}
subview instantiated from another class:
MenuBar.showLogo = false
self.view.insertSubview(messageView.create(viewController: self), belowSubview: view.viewWithTag(1)!)
The problem is that you are setting showLogo but you are not responding to that by setting the logo image's isHidden to true. And it's going to be hard for you to do that so long as showLogo is a static property. Make it an instance property and now you can give it a setter observer.
Related
I am relatively new to Swift.
I have many images (though right now I am testing with four) which I am trying to hide (temporarily to make sure the foundational code is working, instead I really want to insert an image under the tapped image) when they are tapped.
I have created an array of ImageViews which I plan to expand once I have working code. I tried to add UITapGestureRecognizers to each ImageView using a for loop in addGestures() and then have selectImage() hide the tapped ImageView. The code compiles without error, but fails with uncaught NSException when one of these images is tapped. Any tips on how to do this effectively without too much manual coding for each image?
Code attached
Please check below code
func addGestureRecognizer(){
for imageView in imageArray{
imageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(gesture:)))
imageView.addGestureRecognizer(tap)
}
}
#objc func handleTap(gesture:UITapGestureRecognizer){
let imageView = gesture.view
imageView?.isHidden = true
}
in your code you're passing imageView instead of gesture on selector.however you can get imageView by gesture.view.
Also there is no need for separate function for enable userInteraction.
Here is what you can try
class GestureStackVC: UIViewController {
/// Image Outlets
#IBOutlet weak var img1: UIImageView!
#IBOutlet weak var img2: UIImageView!
#IBOutlet weak var img3: UIImageView!
/// ImageView Array
var imagesArray : [UIImageView]?
/// Image Gesture
var imageTapGesture : UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
/// Allocate Array
imagesArray = [UIImageView]()
/// Add Required Values
imagesArray = [img1,img2,img3]
/// Add gesture
for imageView in imagesArray!{
let tap = UITapGestureRecognizer(target: self, action: #selector(imageTapHandler(_:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tap)
}
}
/// tap Handler
#objc func imageTapHandler(_ sender: UITapGestureRecognizer) {
/// Hide the Sender View
sender.view?.isHidden = true
/// Done
}
}
First Output with 3 Images
Output when clicked On first ImageView1 - Results its hidden
Output when clicked On first ImageView2 - Results its hidden
I used to develop for iOS and I do not understand why I can't easily change background color of NSViews inside my main view.
Let's say I have a view controller with a main view in it. In this view I've added 3 custom views, I've set their constraints to fit the main view.
I've created 3 outlets to my view controller:
#IBOutlet weak var topView: NSView!
#IBOutlet weak var leftView: NSView!
#IBOutlet weak var rightView: NSView!
After that, I'm trying to set the background of these views and can't do this. I don't see any color changes when I run the app.
Here is the code I've added to show colors for my custom views:
override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true
self.topView.layer?.backgroundColor = NSColor.blue.cgColor
self.rightView.layer?.backgroundColor = NSColor.green.cgColor
self.leftView.layer?.backgroundColor = NSColor.yellow.cgColor
}
And it shows nothing (no background color on my views):
I can't understand why this code doesn't work. Why it is so hard to set the color of an NSView (while it is so easy in iOS development)? I'm using Xcode 8 and writing code using Swift 3.
You should set wantsLayer to true for your subviews, not for your superview.
self.topView.wantsLayer = true
self.rightView.wantsLayer = true
self.leftView.wantsLayer = true
The layer approach is convenient, but it will create a terrible issue unless you have a very dark background again a bright text color (or vice versa... I don't remember which is which any more.) for an NSTextField label. Unlike Cocoa Touch, which lets you change the background color of a UIView object, unfortunately, you have to subclass NSView in Cocoa for certainty like the following.
import Cocoa
class RedView: NSView {
override func draw(_ rect: NSRect) {
super.draw(rect)
let color = NSColor.red
color.set()
NSRectFill(rect)
}
}
Then set the class name according to whatever you call your subclass (RedView here) under the identity inspector of the interface builder. If you want to change the background color programatically, wire up the view object. Then do something like the following.
import Cocoa
class MyView: NSView {
// MARK: - Variables
var backgroundColor = NSColor()
// MARK: - Draw
override func draw(_ rect:NSRect) {
super.draw(rect)
backgroundColor.set()
NSRectFill(rect)
}
// MARK: - Method
func changeBackgroundColor(color: NSColor) {
backgroundColor = color
setNeedsDisplay(self.bounds)
}
}
You can then call changeBackgroundColor from the view controller like...
#IBOutlet weak var myView: MyView!
myView.changeBackgroundColor(color: NSColor.green)
I have a UIButton inside my cell together with an image and a text label. I manage to change the image and label programatically, but the UIButton does not seem to respond to anything except isHidden.
This is my code, the button that is not changing is followButton:
import UIKit
class ProfileTableCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var followButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
self.profileImage.layer.borderWidth = 0.0;
self.profileImage.layer.cornerRadius = self.profileImage.frame.size.width/2;
self.profileImage.clipsToBounds = true
self.profileImage.image = UIImage(named: "belt")
self.name.text = "Bar Refaeli"
self.followButton.layer.borderColor = UIColor.black.cgColor
self.followButton.layer.borderWidth = 3.0;
self.followButton.layer.cornerRadius = self.frame.size.width/4
self.followButton.backgroundColor = UIColor.black
}
func setCell(image: UIImage, name: String){
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
The profileImage and name outlets change the appearance fine, like mentioned above.
I also tried to remove the button and bring it back in, clean xcode project, remove the outlet reference and connecting it again. Pretty frustrated by now.
I also tried to change the background color of the button through the storyboard, just for testing, and it does not change it! what does change is the titleLabel and the text color.
awakeFromNib()- Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file.
Given that, move your code to a view initiating method like viewDidLoad or viewDidAppear(_:)
Child objects that are attributes like textLabels act differently than child view objects.
Eventually I actually solved this by tossing the table view to the garbage and implementing the same needs using a collection view. there was no problem there..
There seem to be a bunch of questions on this for old versions of Swift/Xcode, but for some reason it hasn't been working with the latest update. I created a NSVisualEffectView, blurryView, and added the subview to my main view:
class ViewController: NSViewController {
#IBOutlet weak var blurryView: NSVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
//background styling
blurryView.wantsLayer = true
blurryView.blendingMode = NSVisualEffectBlendingMode.behindWindow
blurryView.material = NSVisualEffectMaterial.dark
blurryView.state = NSVisualEffectState.active
self.view.addSubview(blurryView, positioned: NSWindowOrderingMode.above, relativeTo: nil)
// Do any additional setup after loading the view.
}
...
}
But when I run it, there is no effect on the window. (when I set it to within window, and layer it on top of my other view, the blur works correctly, but I only want the window to blur.) I also tried doing the same thing in my App Delegate class, but I can't connect my window as an outlet, and therefore can't add the blurry view to the window. Here's what the code would look like:
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
blurryView.wantsLayer = true
blurryView.blendingMode = NSVisualEffectBlendingMode.withinWindow
blurryView.material = NSVisualEffectMaterial.dark
blurryView.state = NSVisualEffectState.active
self.window.contentView?.addSubview(blurryView)
}
...
}
To get an idea if what I'm looking for: NSVisualEffectView Vibrancy
It works quite easy:
In Interface Builder drag a NSVisualEffectView directly as a subview of the main view of your scene.
In the Properties Inspector set Blending Mode to Behind Window
Add the rest of the views you need as subviews of the NSVisualEffectView
That's it, you're done
Here's an example:
Panel 1 View Controller is my blurred view, Background View is the first (non-blurred) view in my "real"view hierarchy.
Swift 5:
Simply add this to your viewWillAppear and it should work:
override func viewWillAppear() {
super.viewWillAppear()
//Adds transparency to the app
view.window?.isOpaque = false
view.window?.alphaValue = 0.98 //you can remove this line but it adds a nice effect to it
let blurView = NSVisualEffectView(frame: view.bounds)
blurView.blendingMode = .behindWindow
blurView.material = .fullScreenUI
blurView.state = .active
view.window?.contentView?.addSubview(blurView)
}
I created a navigation controller with a view controller inside, containing a label. This label should be changed, when the view controller is loaded on tapping a button.
class ViewController: UIViewController {
#IBOutlet weak var btnEmergency: UIButton!
override func viewWillAppear(animated: Bool) {
self.btnEmergency.backgroundColor = UIColor.redColor();
}
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnEmergencyTapped(sender: AnyObject) {
let emergencyViewController = storyboard?.instantiateViewControllerWithIdentifier("EmergencyViewController") as! EmergencyViewController
emergencyViewController.emergencyLabel?.text = "Notruf"
navigationController?.pushViewController(emergencyViewController, animated: true)
}
}
But the label text does not change when loaded. I am relatively new to SWIFT so I try to learn my ropes at the moment using optionals. So I guess the reason is, that the label is not yet instantiated when the view is being loaded on pressing the button. Therefore the default text is being shown and not the text I want to have appear on screen.
I am a little bit stuck at the moment, how to correctly change the label text, when this is an optional. So I guess I cannot expect the label to be there, when I call it. But how do I handle this correctly?
Instead of this, the correct way is to set a property of your emergencyViewController.
In your emergencyViewController viewDidLoad set your label text according to the property set previously.
Anything that you do between initialize of a viewController to viewDidLoad will not take effect.