custom Image of navigationItem.leftBarButtonItem does not stick to the left side - uibarbuttonitem

If I use a custom image for navigationItem.leftBarButtonItem instead of a system one, the button appears in the middle of the bar. If I use a systemImage - no such problem.
Can someone give me any advice how to fix it?
private func configureNavBar() {
var image = UIImage(named: "netflixLogo")
image = image?.withRenderingMode(.alwaysOriginal)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style: .done, target: self, action: nil)
navigationItem.rightBarButtonItems = [
UIBarButtonItem(image: UIImage(systemName: "person"), style: .done, target: self, action: nil),
UIBarButtonItem(image: UIImage(systemName: "play.rectangle"), style: .done, target: self, action: nil)
]
}

Related

Change color of SF Symbols icons

I have a MenuModel struc used to have a list of icons into a table as a menu:
var menu: [MenuModel] = [SideMenuModel(icon: (UIImage(systemName: "house.fill")?.withTintColor(.systemRed))!, title: "Home"),...]
Menu appears but icons still white. I am unable to change colors using the .withTintColor option.
I have also try using it directly on
func tableView(_ tableView: UITableView, cellForRowAt
by:
self.menu[6].icon.withTintColor(.systemRed)
without success.
You can set the image color in a few different ways...
Two options:
if let img = UIImage(systemName: "lock.icloud")?.withTintColor(.systemRed, renderingMode: .alwaysOriginal) {
imgView.image = img
}
or:
if let img = UIImage(systemName: "lock.icloud") {
imgView.image = img
}
imgView.tintColor = .systemRed
Here is some example code... using the first method to create a Red image, and the second method to create a Green image:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let imgViewA = UIImageView()
let imgViewB = UIImageView()
if let img = UIImage(systemName: "lock.icloud")?.withTintColor(.systemRed, renderingMode: .alwaysOriginal) {
imgViewA.image = img
}
if let img = UIImage(systemName: "lock.icloud") {
imgViewB.image = img
}
imgViewB.tintColor = .systemGreen
imgViewA.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imgViewA)
imgViewB.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imgViewB)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
imgViewA.topAnchor.constraint(equalTo: g.topAnchor, constant: 80.0),
imgViewA.centerXAnchor.constraint(equalTo: g.centerXAnchor, constant: 0.0),
imgViewA.heightAnchor.constraint(equalToConstant: 80.0),
imgViewA.widthAnchor.constraint(equalTo: imgViewA.heightAnchor),
imgViewB.topAnchor.constraint(equalTo: imgViewA.bottomAnchor, constant: 20.0),
imgViewB.centerXAnchor.constraint(equalTo: g.centerXAnchor, constant: 0.0),
imgViewB.heightAnchor.constraint(equalToConstant: 80.0),
imgViewB.widthAnchor.constraint(equalTo: imgViewB.heightAnchor),
])
}
}
Result:

SwiftUI exporting the content of Canvas

Does anyone know how to export the content of a Canvas into an Image?
With SwiftUI, it is possible to generate an Image from a View with an extension
func snapshot() -> UIImage {
let controller = UIHostingController(rootView: self)
let view = controller.view
let targetSize = controller.view.intrinsicContentSize
view?.bounds = CGRect(origin: .zero, size: targetSize)
view?.backgroundColor = .clear
let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
This works great for simple views like Button, but for Canvas it always generates an empty image.
For example, with the following code, the image generated by the button is fine, but the one of the Canvas is always empty.
import SwiftUI
extension View {
func snapshot() -> UIImage {
let controller = UIHostingController(rootView: self)
let view = controller.view
let targetSize = controller.view.intrinsicContentSize
view?.bounds = CGRect(origin: .zero, size: targetSize)
view?.backgroundColor = .clear
let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}
struct ContentView: View {
var textView: some View {
Text("Hello, SwiftUI")
.padding()
.background(Color.green)
.foregroundColor(.white)
.clipShape(Capsule())
}
var canvas: some View {
Canvas { context, size in
var path = Path()
path.move(to: CGPoint(x: 0, y:0))
path.addLine(to: CGPoint(x: size.width/2, y:0))
path.addLine(to: CGPoint(x: size.width/2, y:size.height/2))
path.addLine(to: CGPoint(x: 0, y:size.height/2))
path.closeSubpath()
context.fill(path, with: .color(.blue))
}
}
var body: some View {
VStack {
textView
canvas
Button("Save to image: Canvas") {
if let view = canvas as? Canvas<EmptyView> {
let image = view.snapshot()
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
}
Button("Save to image: Text") {
if let view = textView as? Text {
let image = view.snapshot()
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
}
}
}
}
Apply a frame to the canvas and it should work. E.g.
canvas.frame(width: 300, height: 300)
Answer is here: Swift UI exporting content of canvas. Apply the frame in the line where you get the snapshot, i.e.
let newImage = canvasView.frame(width: 300, height: 300).snapshot()

NSImageView (added programmatically) doesn't show image, but shows color

Swift 4. Very simple project, all I did - just added a NSImageView programmatically, backgroundColor and NSImage from the .jpg file. I see the good pink color, but can't see the image at all! I tried many different approaches and some was successful (Image showed up well in collection view and if NSImageView was added manually in the story board) but I need in simple programmatically method. Here is all of my code:
class ViewController: NSViewController {
var image: NSImage = NSImage()
var ivTest = NSImageView()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.ivTest)
self.ivTest.wantsLayer = true
self.ivTest.layer?.backgroundColor = NSColor.systemPink.cgColor
self.ivTest.layer?.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
let manager = FileManager.default
var url = manager.urls(for: .documentDirectory, in: .userDomainMask).first
url = url?.appendingPathComponent("night.jpg")
image = NSImage(byReferencing: url!)
if (image.isValid == true){
print("valid")
print("image size \(image.size.width):\(image.size.height)")
self.ivTest.image = image
} else {
print("not valid")
}
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
output:
result:
thank so much...
--- edited ---
Yes, thank You! Just added this and saw image:
self.ivTest.frame = NSRect(x: 0, y: 0, width: 100, height: 100)

UIWebView show overlapping status bar in ios-11, iPhone-X, Xcode-9

I'm loading a web with UIWebView, everything works fine except that the iphoneX is cut off the bar where I put an "OK" button and a label with a title.
// webView
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: "https://google.com")
let myRequest = URLRequest(url: myURL!)
webView = WKWebView(frame: CGRect( x: 0, y: 60, width: self.view.frame.width, height: self.view.frame.height - 60 ), configuration: WKWebViewConfiguration() )
//webView.backgroundColor = UIColor.blue
self.view.addSubview(webView)
webView.load(myRequest)
self.webView.allowsBackForwardNavigationGestures = true
//hide navegation bar
self.navigationController?.setNavigationBarHidden(true, animated: true)
// add cornerRadius to view
navegador.layer.cornerRadius = 10
//add observer to get estimated progress value
self.webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
}
Any suggestions to solve this impasse.
The height of the StatusBar in the iPhoneX is higher than in the other devices, it is necessary to calculate this height and use this value for the WebView coordinates.
Add a view to place the OK button:
#IBOutlet weak var myTopBar: UIView!
Calculate height of statusBar:
//Get height status bar
let statusBarHeight = UIApplication.shared.statusBarFrame.height
// to see correctly on all device models the new height will be:
let heightTotal = self.myTopBar.frame.height + statusBarHeight
3: In the webView, use this height:
webView = WKWebView(frame: CGRect( x: 0, y: heightTotal, width: self.view.frame.width, height: self.view.frame.height - heightTotal), configuration: WKWebViewConfiguration() )

NSSavePanel accessoryView: Why doesn't my button appear?

I am creating a save panel with an accessoryView that contains a single checkbox. I can get it to work when I create the button using:
NSButton(checkboxWithTitle: "Check Me", target: self, action: #selector(checkBoxSelected))
But this gives me a warning that this particular NSButton initializer requires macOS 10.12 and I need to support 10.10.
Here's my savePanel setup:
#IBAction func save(_ sender: NSButton) {
let savePanel = NSSavePanel()
savePanel.accessoryView = accessoryView()
savePanel.runModal()
}
And here's how I create my accessory view in Sierra
func accessoryView() -> NSView {
let checkbox = NSButton(checkboxWithTitle: "Check Me", target: self, action: #selector(checkBoxSelected))
let view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 100))
view.addSubview(checkbox)
return view
}
But this doesn't work (the button doesn't appear)
func accessoryView() -> NSView {
let checkbox = NSButton()
checkbox.setButtonType(NSSwitchButton)
checkbox.title = "Check Me"
checkbox.state = 1
checkbox.target = self
checkbox.action = #selector(checkBoxSelected)
let view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 100))
view.addSubview(checkbox)
return view
}
Got it.
Need to use NSButton.init(frame:)
Thanks

Resources