I am programmatically creating a window that needs to span across 2 screens. the size of the window being created is correct but the window is starting about halfway across the first screen. I can drag it back to the beginning of the first screen and the NSWindow fits perfectly.
I just need to know where I'm going wrong in terms of the starting point for the window.
func createNewWindow() {
let bannerWidth = NSScreen.screens[0].frame.width * 2
let bannerHeight = NSScreen.screens[0].frame.height
let rect = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: bannerWidth, height: bannerHeight))
let newWindow = NSWindow(contentRect: rect, styleMask: [.closable], backing: .buffered, defer: false)
let storyboard = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "ExternalScreen") as? NSViewController
let window = storyboard?.view
newWindow.styleMask.update(with: .resizable)
NSMenu.setMenuBarVisible(false)
newWindow.title = "New Window"
newWindow.isOpaque = false
newWindow.isMovableByWindowBackground = true
newWindow.backgroundColor = NSColor(calibratedHue: 0, saturation: 1.0, brightness: 0, alpha: 0.7)
newWindow.toggleFullScreen(true)
newWindow.makeKeyAndOrderFront(nil)
newWindow.toolbar?.isVisible = false
newWindow.contentView?.addSubview(window!)
}
You're setting the content rectangle, but not setting the frame. The frame is the rectangle that the window occupies in screen coordinates. To move the window, you can setFrameOrigin() or setFrameTopLeftPoint().
Related
I have a tab bar that I'm trying to customize it's look. So far, I changed it's background color and added corner radius. I'm trying to add a shadow to it, but I can't get it to work.
I tried few solutions, but nothing worked for me. There is not errors or anything, but it just won't work. This is what I have so far:
private func setupTabBarAppearance() {
let CORNER_RADIUS: CGFloat = 20
let tabBar = self.tabBar
tabBar.barTintColor = UIColor.appWhite
tabBar.unselectedItemTintColor = .lightGray
tabBar.tintColor = UIColor.appBlue
tabBar.layer.masksToBounds = true
tabBar.layer.cornerRadius = CORNER_RADIUS
tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
tabBar.layer.shouldRasterize = true
let shapeLayer = CAShapeLayer()
let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: tabBar.frame.height), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: CORNER_RADIUS, height: CORNER_RADIUS)).cgPath
shapeLayer.path = path
shapeLayer.shadowColor = UIColor.black.cgColor
shapeLayer.shadowOffset = CGSize(width: 2, height: 5)
shapeLayer.shadowOpacity = 1
shapeLayer.shadowRadius = 10
shapeLayer.shouldRasterize = true
shapeLayer.rasterizationScale = UIScreen.main.scale
tabBar.layer.rasterizationScale = UIScreen.main.scale
tabBar.layer.addSublayer(shapeLayer)
}
I have two problems with this that I don't find a solution to, which is:
I can't get the shapeLayer to be behind tabBar, it just covers it.
The shadow from shapeLayer is facing downwards so even if I would be able to get the shapeLayer to be behind the tab bar, the shadow still won't be displayed.
Let’s just tackle this part:
tabBar.layer.addSublayer(shapeLayer)
Obviously if you add a shape layer to the tab bar’s own layer, the shape layer must be in front. That is what it means to be a sublayer.
If you want to cast a shadow using a custom shape, you will need a completely separate view hidden behind your tab bar.
I want to change the NSView's geometry to the top-left corner. But the result isn't correct.( PS: the result is correct on the iOS platform.)
my code like this & the effect is as follows:
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true
self.view.layer?.isGeometryFlipped = true
let red = NSView(frame: NSRect(origin: .zero, size: CGSize(width: 400, height: 200)))
red.wantsLayer = true
red.layer?.backgroundColor = NSColor.red.cgColor
let yellow = NSView(frame: NSRect(origin: .zero, size: CGSize(width: 200, height: 100)))
yellow.wantsLayer = true
yellow.layer?.backgroundColor = NSColor.yellow.cgColor
red.addSubview(yellow)
view.addSubview(red)
}
}
Why I set the property isGeometryFlipped= true of View's layer, the geometry isn't change
from bottom-left corner to the top-left corner?
It's because coordinate system in iOS and macOS are not the same.
Point (x:0, y:0) in :
- iOS : at the top left
macOS : at the bottom left
if you want the yellow view at the top left of the red view,just do this:
let yellow = NSView(frame: NSRect(origin: CGPoint(x: 0, y: 400), size: CGSize(width: 200, height: 100)))
I've been trying to make a zoom animation like Facebook when you click a picture into a cell to move into the middle of the screen. The animation works, but for a reason that I can not figure out, it is not starting from the initial position it is giving me another frame. Please help, I've been struggling with this for a few days now.
I am using a collectionView with CustomCell and everything it's done programmatically:
The function in CenterVC:
//MARK: Function to animate Image View (it will animate to the middle of the View)
func animateImageView(statusImageView : UIImageView) {
//Get access to a starting frame
statusImageView.frame.origin.x = 0
if let startingFrame = statusImageView.superview?.convert(statusImageView.frame, to: nil) {
//Add the view from cell to the main view
let zoomImageView = UIView()
zoomImageView.backgroundColor = .red
zoomImageView.frame = statusImageView.frame
view.addSubview(zoomImageView)
print("Starting frame is: \(startingFrame)")
print("Image view frame is: \(statusImageView.frame)")
UIView.animate(withDuration: 0.75, animations: {
let height = (self.view.frame.width / startingFrame.width) * startingFrame.height
let y = self.view.frame.height / 2 - (height / 2)
zoomImageView.frame = CGRect(x: 0, y: y, width: self.view.frame.width, height: height)
})
}
}
This is the pictureView inside the cell and the constraints (this is where I am setting up the picture for the view, and I am using in cellForRowAtIndexPath cell.centerVC = self):
var centerVC : CenterVC?
func animate() {
centerVC?.animateImageView(statusImageView: pictureView)
}
let pictureView : UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.image = UIImage(named: "cat")
imageView.backgroundColor = UIColor.clear
imageView.layer.masksToBounds = true
imageView.isUserInteractionEnabled = true
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
addConstraintsWithFormat(format: "V:|-5-[v0(40)]-5-[v1]-5-[v2(200)]", views: profileImage, postTextView, pictureView)
addConstraintsWithFormat(format: "H:|[v0]|", views: pictureView)
This is what it prints out in the debugger:
Starting frame is: (5.0, 547.5, 365.0, 200.0)
Image view frame is: (0.0, 195.5, 365.0, 200.0)
As you can see the starting frame it's different from the initial frame and position of the picture. The animation it's not leaving the initial position it just appears somewhere on top and animates to the middle. I don't know what to do, please advice.
For some reason, it was not reading the starting frame rect so I've made a new CGRect that gets the origin and set the size of the picture: (it animates perfectly now)
zoomImageView.frame = CGRect(origin: startingFrame.origin, size: CGSize(width: view.frame.width, height: statusImageView.frame.height))
I'm trying to make an UITextField as a SCNNode geometry material. This code works well:
func createBox(transform: SCNMatrix4) {
let box = SCNBox(width: 0.5, height: 0.5, length: 0.5, chamferRadius: 1)
let textField = UITextField(frame: CGRect(x: 0, y: 0, width: 60, height: 50))
textField.text = "Hello"
let sides = [
textField, // Front
UIColor.black, // Right
UIColor.black, // Back
UIColor.black, // Left
UIColor.black, // Top
UIColor.black // Bottom
]
let materials = sides.map { (side) -> SCNMaterial in
let material = SCNMaterial()
material.diffuse.contents = side
material.locksAmbientWithDiffuse = true
return material
}
box.materials = materials
let boxNode = SCNNode(geometry: box)
boxNode.position = SCNVector3Make(transform.m41, transform.m42, transform.m43)
boxNode.transform = transform
sceneView.scene.rootNode.addChildNode(boxNode)
}
But when I tap on the text field the keyboard doesn't appear. Why is it happening? Is there ways to fix it? I need the user can enter some text in the field. Thanks.
I'm have the Facebook login button to my app, but when I can't move it from the top left corner to the center of the screen.
I tried:
loginButton.center = (self.view?.center)!
and
loginButton.frame = CGRect(origin: CGPoint(x: self.frame.midX,y :self.frame.midY), size: CGSize(width: loginButton.frame.width, height: loginButton.frame.height))
but neither worked, the center variable changes but the button remains in the top left corner
Does anyone knows how to fix this?
I'm adding the button with this code
let loginButton: FBSDKLoginButton = {
let button = FBSDKLoginButton()
button.readPermissions = ["email"]
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
view.addSubview(loginButton)
You should set your code like this:
let loginButton = FBSDKLoginButton(frame: CGRect(x: 0, y: 0, width: //whatever width you want, height: //whatever height you want))
loginButton.readPermissions = ["email"]
loginButton.center = view.center
view.addSubview(loginButton)
Refer to https://developers.facebook.com/docs/facebook-login/ios#loginkit