Weird NSButton creation - swift

I have a simple AppDelegate like this:
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var field: NSView!
let button = NSButton()
let buttons = [NSButton(), NSButton(), NSButton()]
func applicationDidFinishLaunching(aNotification: NSNotification) {
button.frame = NSMakeRect(30, 60, 80, 25)
button.title = "ok"
field.addSubview(button)
for index in 0...2 {
let buttonI = buttons[index]
buttonI.frame = NSMakeRect(30+CGFloat(index)*90, 30, 80, 25)
buttonI.title = "not ok:\(index)"
field.addSubview(buttonI)
}
}
}
(You can test the above by connecting field with a custom view inside the content view of the window).
When I run this I get the following button appearance:
Why is it that the single button looks ok while those from the array are not?

You just need to set the bezelStyle:
button.bezelStyle = .RoundedBezelStyle
buttonI.bezelStyle = .RoundedBezelStyle

Related

Value of type 'SecondPageController' has no member 'miniView'

I got seems similar but little bit different question.
It is about declare size issue, but have small error here.
I think error is related to Main.stroyboard, and tried to change ViewController name and also added 'miniView' to ViewController.
My error is
"Value of type 'SecondPageController' has no member 'miniView'",
Witch is very common error(I looked many of same question with this format), but I think my error is relate to adding some new view or something.
And here is my code.
class SecondPageController: UIViewController {
#IBOutlet weak var mainScrollView: UIScrollView!
var imageArray = [UIImage]()
var currentPage = 0
override func viewDidLoad() {
super.viewDidLoad()
imageArray = [UIImage(named: "bus1")!, UIImage(named: "bus2")!]
for i in 0..<imageArray.count {
let imageView = UIImageView()
imageView.image = imageArray[i]
imageView.contentMode = .scaleAspectFit
let xPosition = self.miniView.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
}
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(startAnimating), userInfo: nil, repeats: true)
}
#objc func startAnimating() {
//that line check if the current page is the last one, and set it to the first, otherwise, it increment the currentPage
self.currentPage = (self.currentPage == imageArray.count-1) ? 0 : self.currentPage+1
var newOffset = mainScrollView.contentOffset
newOffset.x = mainScrollView.frame.width * CGFloat(self.currentPage)
self.mainScrollView.setContentOffset(newOffset, animated: true)
}
}
I expecting add something to this error solved.
There is no member miniView in SecondPageController. The error was very precise.
If you wanna use a component named miniView you need a reference to it, you can use 2 approaches:
1 - Storyboard:
Drag a view to your UIViewController and link it to #IBOutlet weak var miniView: UIView!
2 - Programatic:
Instantiate it like: let miniView = UIView()
Since you are using Storyboards, you probably forgot to add an #IBOutletto that view, so use approach 1.

Check text field Live

I have found this answer How to check text field input at real time?
This is what I am looking for. However I am having trouble actually implementing this code. Also my current geographical location makes googling almost impossible.
I want to be able to change the background color of the next text field if the correct number is entered into the previous text field. textfieldTwo background color will change to green if the correct value is entered in textFieldOne. If the value is incorrect then nothing will happen. Please help me out. I have two text fields called textFieldOne and textFieldTwo and nothing else in the code.
Just pop this in your main view controller in an empty project (try using iphone 6 on the simulator)
import UIKit
class ViewController: UIViewController {
var txtField:UITextField!
var txtFieldTwo:UITextField!
var rightNumber = 10
override func viewDidLoad() {
super.viewDidLoad()
//txtFieldOne
var txtField = UITextField()
txtField.frame = CGRectMake(100, 100, 200, 40)
txtField.borderStyle = UITextBorderStyle.None
txtField.backgroundColor = UIColor.blueColor()
txtField.layer.cornerRadius = 5
self.view.addSubview(txtField)
//txtFieldTwo
var txtFieldTwo = UITextField()
txtFieldTwo.frame = CGRectMake(100, 150, 200, 40)
txtFieldTwo.borderStyle = UITextBorderStyle.None
txtFieldTwo.backgroundColor = UIColor.blueColor()
txtFieldTwo.layer.cornerRadius = 5
self.view.addSubview(txtFieldTwo)
txtField.addTarget(self, action: "checkForRightNumber", forControlEvents: UIControlEvents.AllEditingEvents)
self.txtField = txtField
self.txtFieldTwo = txtFieldTwo
}
func checkForRightNumber() {
let number:Int? = self.txtField.text.toInt()
if number == rightNumber {
self.txtFieldTwo.backgroundColor = UIColor.greenColor()
} else {
self.txtFieldTwo.backgroundColor = UIColor.blueColor()
}
}
}
EDIT: Adding a version with IBOutlets and IBActions
Note that in this example the IBAction is connected to txtFieldOne on Sent Events / Editing Changed
Also, make sure your Text Fields border colors are set to None. In the storyboard, the way to do this is to choose the left most option with the dashed border around it. That's so you can color the backgrounds. You can use layer.cornerRadius to set the roundness of the border's edges.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var txtField: UITextField!
#IBOutlet weak var txtFieldTwo: UITextField!
var rightNumber = 10
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func checkForRightNumber(sender: AnyObject) {
let number:Int? = self.txtField.text.toInt()
if number == rightNumber {
self.txtFieldTwo.backgroundColor = UIColor.greenColor()
} else {
self.txtFieldTwo.backgroundColor = UIColor.blueColor()
}
}
}

Swift delegation and storyboard #IBDesignable issue

Below is just a test of delegation.
What I did was, 1) draw a rectangle, 2) set this rectangle's width of line with a delegate, 3) Hope the storyboard could update its display.
There are two questions:
The first is: If I use "testView.widthdelegate = ViewController()" rather than "testView.widthdelegate = self" , the "var widthValue: CGFloat? = widthdelegate?.trueWidth" will be nil, but it should be 50, what's different between "self" and "ViewController()"?
The second is: I still want to update the result of draw in storyboard, where you can see I did a SetNeedDisplay() but no use at all, how could I do it?
View
import UIKit
protocol widthDelegate: class {
var trueWidth: CGFloat { get }
}
#IBDesignable
class TestView: UIView {
weak var widthdelegate: widthDelegate?
override func drawRect(rect: CGRect) {
var widthValue: CGFloat? = widthdelegate?.trueWidth ?? 1.0
rectangle(widthRefer: widthValue!)
println("width in TestView is \(widthdelegate?.trueWidth)" )
}
func rectangle(#widthRefer: CGFloat) -> UIBezierPath{
var rect = UIBezierPath(rect: CGRect(x: bounds.width/2-50, y: bounds.height/2-50, width: 100, height: 100))
rect.lineWidth = widthRefer
rect.stroke()
return rect
}
}
Controller
import UIKit
class ViewController: UIViewController,widthDelegate {
var trueWidth: CGFloat = 50
#IBOutlet var testView: TestView!{
didSet{ //after the storyboard loaded.
// testView.widthdelegate = ViewController()
testView.widthdelegate = self
testView.setNeedsDisplay()
}
}
}
Answer 1:
self is the actual instance of the class the code is in (correct solution)
ViewController() creates a brand new instance of ViewController which is not identical with the instance created in IB (wrong solution)
Answer 2:
Never implement didSet for an IBOutlet because it's never called during initialization. Better use viewDidLoad() for settings
Some other notes:
Please consider the naming convention that class, protocol and enum names start with a capital letter.
The class constraint in the protocol declaration is not needed

How do I change the CGRect to buttons?

I originally used rectangles to test out the program but now I need to make them buttons. How would I do that programmatically?
import UIKit
class interestViewController: UIViewController {
var squareView: UIView!
var square: UIView!
var frogs: UIView!
var colson: UIView!
var wwdc: UIView!
var gravity: UIGravityBehavior!
var animator: UIDynamicAnimator!
var collision: UICollisionBehavior!
override func viewDidLoad() {
super.viewDidLoad()
squareView = UIView(frame: CGRectMake(100, 100, 100, 100))
view.addSubview(squareView)
animator = UIDynamicAnimator(referenceView: view)
squareView.backgroundColor = UIColor.blackColor()
gravity = UIGravityBehavior(items: [squareView])
animator.addBehavior(gravity)
collision = UICollisionBehavior(items: [squareView])
collision.translatesReferenceBoundsIntoBoundary = true
animator.addBehavior(collision)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Question: How would I do that programmatically?
Short answer: Don't. Create your buttons in IB. It's easier than code the first time, and way, waaaaay easier to update and maintain. Learn to use IB. It's a huge timesaver.
If you are bound and determined to do things the hard way, then you'll need to use one of the UIButton class initializers, like buttonWithType. Then you'd set the frame and other attributes like you're doing with your squareView.

Creating a view above an object

I'm attempting to create a scene in Swift in which an object (object is a button) is clicked and it creates a pop-up window above the clicked building. I thought i had it down until it gave me an error saying, unexpected nil value when unwrapping an optional or something nasty like that. Here's the code. Thanks for any fixes you may have.
import UIKit
class BuildingUI {
//props
enum buildingTypes {
case residential
case commercial
}
var xValue : CGFloat = 0
var width : CGFloat = 0
//methods
func createBuildingView(xValue : CGFloat, width : CGFloat, buildingType : buildingTypes) {
self.xValue = (xValue+(width/2))
playScreenIns.BuildingView1.frame = CGRect(x: self.xValue, y: playScreenIns.PlayView.frame.height/10, width: (playScreenIns.PlayView.frame.width/5)*3, height: playScreenIns.PlayView.frame.height/4)
playScreenIns.BuildingView1.backgroundColor = UIColor.lightGrayColor()
playScreenIns.BuildingView1.layer.borderWidth = 2
playScreenIns.BuildingView1.layer.borderColor = UIColor.darkGrayColor().CGColor
playScreenIns.BuildingView1.layer.cornerRadius = 25
playScreenIns.scroller.addSubview(playScreenIns.BuildingView1)
}
}
var BuildingUIIns = BuildingUI()
import UIKit
class PlayScreen : UIViewController {
#IBOutlet var PlayView: UIView!
var BuildingView1 : UIView!
#IBAction func CityHallPress(sender: UIButton!) {
BuildingUIIns.createBuildingView(sender.frame.origin.x, width: sender.frame.width, buildingType: .residential)
}
}
var playScreenIns = PlayScreen()
After reviewing your code, and commenting. I believe what you want is
BuildingUI should inherit UIView
class BuildingUI: UIView {}
then in your PlayScreen the BuildingView1 should be of type BuildingUI.
But, I am not so sure on what you're trying to do...are you doing this as experimental test in playground?
On a side note, you should name your your classes with a postfix to what kind of class your inheriting from for example
BuildingUI should be BuildingView and PlayScreen should be PlayScreenViewController
you should start your class properties with a lower case BuildingView1 to buildinvView1 like you do in BuildingUI. But its matter of taste I guess!