swift show up window programmatically - popup

Im writing on a command line tool that shows a pop up window.
Of course programmatically.
In this pop up window I show two text fields, one for the username and the other for password. But when I try to type text in one of them, it wont work. I can select the textField and everything but when I try to type text it wont show up
Can anyone help me please
Edit:
Here's the code:
main.swift:
import Foundation
import AppKit
let app = NSApplication.sharedApplication()
let con = TestApplicationController()
app.delegate = con
app.run()
window.swift:
import Foundation
import AppKit
final class TestApplicationController: NSObject, NSApplicationDelegate {
let window1 = NSWindow()
let view = NSView()
func applicationDidFinishLaunching(aNotification: NSNotification) {
window1.setFrame(CGRect(x: 0, y: 0, width: 443, height: 229), display: true)
window1.contentView = view
window1.opaque = false
window1.center()
window1.makeKeyAndOrderFront(self)
window1.title = "Finder"
window1.level = Int(CGWindowLevelForKey(.MaximumWindowLevelKey))
window1.makeKeyAndOrderFront(self)
// MARK: - Name Label
let nameLabel: NSTextField = NSTextField(frame: NSMakeRect(138, 101, 44, 17))
nameLabel.editable = false
nameLabel.drawsBackground = false
nameLabel.bezeled = false
nameLabel.selectable = false
nameLabel.stringValue = "Name:"
windowContentView.addSubview(nameLabel)
// MARK: - Password Label
let passwordLabel: NSTextField = NSTextField(frame: NSMakeRect(118, 69, 64, 17))
passwordLabel.editable = false
passwordLabel.drawsBackground = false
passwordLabel.bezeled = false
passwordLabel.selectable = false
passwordLabel.stringValue = "Passwort:"
windowContentView.addSubview(passwordLabel)
// MARK: - Name Field
let nameField: NSTextField = NSTextField(frame: NSMakeRect(190, 98, 233, 22))
nameField.editable = true
nameField.selectable = true
nameField.stringValue = "Michael"
nameField.action = "nameEdited:"
windowContentView.addSubview(nameField)
// MARK: - Password Field
let passwordField: NSSecureTextField = NSSecureTextField(frame: NSMakeRect(190, 66, 233, 22))
passwordField.editable = true
passwordField.selectable = true
passwordField.stringValue = ""
passwordField.becomeFirstResponder()
passwordField.action = "passwordEdited:"
windowContentView.addSubview(passwordField)
func nameEdited(sender: NSTextField){
print("editedname")
}
func passwordEdited(sender: NSTextField){
print("editedpw")
}
}

Related

Truncate value label of PieChart in Charts Library Swift

`class PieChartViewController: DemoBaseViewController {
#IBOutlet var chartView: PieChartView!
#IBOutlet var sliderX: UISlider!
#IBOutlet var sliderY: UISlider!
#IBOutlet var sliderTextX: UITextField!
#IBOutlet var sliderTextY: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Pie Chart"
self.setup(pieChartView: chartView)
chartView.delegate = self
chartView.holeRadiusPercent = 0.8
chartView.usePercentValuesEnabled = true
chartView.transparentCircleRadiusPercent = 0
chartView.drawHoleEnabled = true
chartView.transparentCircleColor = UIColor.white.withAlphaComponent(1)
chartView.drawCenterTextEnabled = true
chartView.centerText = nil
let l = chartView.legend
l.enabled = false
//MARK: Entry label Styling (Value Label Above PieChart)
chartView.entryLabelColor = .black
chartView.entryLabelFont = .systemFont(ofSize: 14, weight: .medium)
//MARK: Setting Offset
let frameOffset = chartView.frame.width * 0.12
chartView.setExtraOffsets(left: frameOffset, top: frameOffset, right: frameOffset, bottom: frameOffset)
self.slidersValueChanged(nil)
}
override func updateChartData() {
if self.shouldHideData {
chartView.data = nil
return
}
self.setDataCount()
}
func setDataCount() {
let entry1 = PieChartDataEntry(value: 22, label: "Apple.It is a fruit")
let entry2 = PieChartDataEntry(value: 33, label: "Zebra.It is an animal")
let entry3 = PieChartDataEntry(value: 31, label: "Eagle.It is a bird")
let entry4 = PieChartDataEntry(value: 14, label: "Asia.It is a continent")
var enteries: [PieChartDataEntry] = []
enteries.append(entry1)
enteries.append(entry2)
enteries.append(entry3)
enteries.append(entry4)
let set = PieChartDataSet(entries: enteries, label: "Knowledge")
set.drawIconsEnabled = false
set.sliceSpace = 0
set.selectionShift = 0
set.colors = ChartColorTemplates.vordiplom()
+ ChartColorTemplates.joyful()
+ ChartColorTemplates.colorful()
+ ChartColorTemplates.liberty()
+ ChartColorTemplates.pastel()
+ [UIColor(red: 51/255, green: 181/255, blue: 229/255, alpha: 1)]
// MARK: Setting Value Label
set.valueLinePart1OffsetPercentage = 0.20
set.valueLinePart1Length = 0.4
set.valueLinePart2Length = 0.4
set.valueLineColor = .black
set.valueTextColor = .black
set.xValuePosition = .outsideSlice
set.yValuePosition = .outsideSlice
let data = PieChartData(dataSet: set)
data.setValueFont(.systemFont(ofSize: 13, weight: .medium))
data.setValueTextColor(.black)
chartView.data = data
chartView.highlightValues(nil)
}
override func optionTapped(_ option: Option) {
chartView.setNeedsDisplay()
}
// MARK: - Actions
#IBAction func slidersValueChanged(_ sender: Any?) {
self.updateChartData()
}
}`
How to truncate or word wrap the value label in Pie Chart ?
I am using Charts Library in iOS.
If I add extra offset the pie chart shrink in smaller devices like iPhone 5s or iPhone SE.
If the text is large then the text goes out of the screen as you can see in the uploaded image. I am not able to find any properties (word wrap) to handle the large text issue.

trying to add a textfield into an nsmenuitem but it wont show up

here is the code i use to try to add a textfield into an nsmenuitem
class menuitemtest1: NSTextField {
var menuitemtest1 = NSTextField()
override func viewDidChangeBackingProperties() {
menuitemtest1.frame = CGRect(x: 220, y: 8, width: 103, height: 17)
menuitemtest1.stringValue = "Maximum Lenght"
menuitemtest1.isEditable = false
menuitemtest1.textColor = .gray
menuitemtest1.isSelectable = false
menuitemtest1.drawsBackground = false
}
}
thats the class
and how i add it
var textFieldInMenutest = NSMenuItem()
menuBarMenu.addItem(textFieldInMenutest)
textFieldInMenutest.view = menuitemtest1()
You created an NSTextField subclass which has as a property, a separate and direct NSTextField instance. This makes no sense. What you intended to do, was this:
class menuitemtest1: NSTextField {
override func viewDidChangeBackingProperties() {
self.frame = CGRect(x: 220, y: 8, width: 103, height: 17)
self.stringValue = "Maximum Lenght"
self.isEditable = false
self.textColor = .gray
self.isSelectable = false
self.drawsBackground = false
}
}
As for why it "doesn't show up" — the text field you did add as the menu item's view has a zero-sized (default) frame, so it's simply invisible.
Further, viewDidChangeBackingProperties is not the correct place to set up basic properties of the field. In such a subclass, you should use the initializer, init(frame:... or init(coder: ...

Line chart fill color is faded

I am trying to setup a line chart with one fill colour but for some reason, the fill colour is faded.
Example
Both the random view I have added to middle of screen and the fill colour of the line chart are set to be red, but for some reason the fill colour of the chart is faded.
Can see code here
#IBOutlet var liveChart : LineChartView!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Chart Tests"
configureChart(chart: liveChart)
var xAxis = [String]()
var yAxis = [Double]()
for _ in 0..<10
{
xAxis.append("")
let yVal = Double(randomBetweenNumbers(firstNum: 1.0, secondNum: 100.0))
yAxis.append(yVal)
}
setData(xAxisArray: xAxis, yAxisArray: yAxis, chart: liveChart)
let testView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
testView.center = view.center
testView.backgroundColor = UIColor.red
view.addSubview(testView)
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat{
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}
func configureChart(chart : LineChartView)
{
chart.chartDescription?.text = ""
chart.noDataText = "Loading Data"
chart.backgroundColor = UIColor.clear
chart.drawGridBackgroundEnabled = false
chart.dragEnabled = true
chart.rightAxis.enabled = false
chart.leftAxis.enabled = true
chart.doubleTapToZoomEnabled = false
chart.legend.enabled = false
chart.pinchZoomEnabled = true
chart.highlightPerTapEnabled = false
chart.highlightPerDragEnabled = false
chart.xAxis.enabled = false
chart.leftAxis.drawAxisLineEnabled = false
chart.leftAxis.drawGridLinesEnabled = false
chart.leftAxis.labelCount = 5
chart.leftAxis.forceLabelsEnabled = true
}
func setData(xAxisArray : [String], yAxisArray : [Double], chart : LineChartView)
{
var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
if(xAxisArray.count > 0)
{
for i in 0 ..< xAxisArray.count
{
let chartEntry = ChartDataEntry(x: Double(i), y: yAxisArray[i], data: nil)
yVals1.append(chartEntry)
}
}
let set1: LineChartDataSet = LineChartDataSet(values: yVals1, label: "")
set1.fillColor = UIColor.red
set1.drawFilledEnabled = true
set1.drawCirclesEnabled = false
let data = LineChartData()
data.addDataSet(set1)
liveChart.data = data
}
Is there a way to fix this? Or is this just the way the fill colour of the chart works?
Edit:
I am using
https://github.com/danielgindi/Charts
I assume you use this library: https://github.com/kevinbrewster/SwiftCharts
So the LineChartView automatically set alpha for the fill color: https://github.com/kevinbrewster/SwiftCharts/blob/master/SwiftCharts/LineChart.swift#L758
try to set fillAlpha property of the data set

Swift add badge to navigation barButtonItem and UIButton

I am trying to display badge on my notification button, in app as displayed on AppIcon.
So far whatever i have researched is related to Obj. C, but nothing that specifically discussed way to implement that solution into Swift,
Please help to find a solution to add a custom class / code to achieve Badge on UiBarbutton and UiButton.
Researched so far:
https://github.com/Marxon13/M13BadgeView
along with MKBadge class etc.
There is a more elegant solution with an extension for UIButtonItem
extension CAShapeLayer {
func drawCircleAtLocation(location: CGPoint, withRadius radius: CGFloat, andColor color: UIColor, filled: Bool) {
fillColor = filled ? color.cgColor : UIColor.white.cgColor
strokeColor = color.cgColor
let origin = CGPoint(x: location.x - radius, y: location.y - radius)
path = UIBezierPath(ovalIn: CGRect(origin: origin, size: CGSize(width: radius * 2, height: radius * 2))).cgPath
}
}
private var handle: UInt8 = 0
extension UIBarButtonItem {
private var badgeLayer: CAShapeLayer? {
if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject? {
return b as? CAShapeLayer
} else {
return nil
}
}
func addBadge(number: Int, withOffset offset: CGPoint = CGPoint.zero, andColor color: UIColor = UIColor.red, andFilled filled: Bool = true) {
guard let view = self.value(forKey: "view") as? UIView else { return }
badgeLayer?.removeFromSuperlayer()
// Initialize Badge
let badge = CAShapeLayer()
let radius = CGFloat(7)
let location = CGPoint(x: view.frame.width - (radius + offset.x), y: (radius + offset.y))
badge.drawCircleAtLocation(location: location, withRadius: radius, andColor: color, filled: filled)
view.layer.addSublayer(badge)
// Initialiaze Badge's label
let label = CATextLayer()
label.string = "\(number)"
label.alignmentMode = CATextLayerAlignmentMode.center
label.fontSize = 11
label.frame = CGRect(origin: CGPoint(x: location.x - 4, y: offset.y), size: CGSize(width: 8, height: 16))
label.foregroundColor = filled ? UIColor.white.cgColor : color.cgColor
label.backgroundColor = UIColor.clear.cgColor
label.contentsScale = UIScreen.main.scale
badge.addSublayer(label)
// Save Badge as UIBarButtonItem property
objc_setAssociatedObject(self, &handle, badge, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func updateBadge(number: Int) {
if let text = badgeLayer?.sublayers?.filter({ $0 is CATextLayer }).first as? CATextLayer {
text.string = "\(number)"
}
}
func removeBadge() {
badgeLayer?.removeFromSuperlayer()
}
}
This great code was created by Stefano Vettor and you can find all the details at:
https://gist.github.com/freedom27/c709923b163e26405f62b799437243f4
Working Solution :
Step 1:
Firstly create new swift file which is a subclass to UIButton as follows:
import UIKit
class BadgeButton: UIButton {
var badgeLabel = UILabel()
var badge: String? {
didSet {
addbadgetobutton(badge: badge)
}
}
public var badgeBackgroundColor = UIColor.red {
didSet {
badgeLabel.backgroundColor = badgeBackgroundColor
}
}
public var badgeTextColor = UIColor.white {
didSet {
badgeLabel.textColor = badgeTextColor
}
}
public var badgeFont = UIFont.systemFont(ofSize: 12.0) {
didSet {
badgeLabel.font = badgeFont
}
}
public var badgeEdgeInsets: UIEdgeInsets? {
didSet {
addbadgetobutton(badge: badge)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
addbadgetobutton(badge: nil)
}
func addbadgetobutton(badge: String?) {
badgeLabel.text = badge
badgeLabel.textColor = badgeTextColor
badgeLabel.backgroundColor = badgeBackgroundColor
badgeLabel.font = badgeFont
badgeLabel.sizeToFit()
badgeLabel.textAlignment = .center
let badgeSize = badgeLabel.frame.size
let height = max(18, Double(badgeSize.height) + 5.0)
let width = max(height, Double(badgeSize.width) + 10.0)
var vertical: Double?, horizontal: Double?
if let badgeInset = self.badgeEdgeInsets {
vertical = Double(badgeInset.top) - Double(badgeInset.bottom)
horizontal = Double(badgeInset.left) - Double(badgeInset.right)
let x = (Double(bounds.size.width) - 10 + horizontal!)
let y = -(Double(badgeSize.height) / 2) - 10 + vertical!
badgeLabel.frame = CGRect(x: x, y: y, width: width, height: height)
} else {
let x = self.frame.width - CGFloat((width / 2.0))
let y = CGFloat(-(height / 2.0))
badgeLabel.frame = CGRect(x: x, y: y, width: CGFloat(width), height: CGFloat(height))
}
badgeLabel.layer.cornerRadius = badgeLabel.frame.height/2
badgeLabel.layer.masksToBounds = true
addSubview(badgeLabel)
badgeLabel.isHidden = badge != nil ? false : true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addbadgetobutton(badge: nil)
fatalError("init(coder:) is not implemented")
}
}
Step 2:
Create a function in your base file which u can use in each View Controller :
func addBadge(itemvalue: String) {
let bagButton = BadgeButton()
bagButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
bagButton.tintColor = UIColor.darkGray
bagButton.setImage(UIImage(named: "ShoppingBag")?.withRenderingMode(.alwaysTemplate), for: .normal)
bagButton.badgeEdgeInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 15)
bagButton.badge = itemvalue
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: bagButton)
}
Step 3 :
Use above function from any View Controller in this way :
self.addBadge(itemvalue: localStorage.string(forKey: "total_products_in_cart") ?? "0")
First create label, then right bar button. On right bar button add subview which will be badge count. Finally add navigation right bar button.
SWIFT 5
let badgeCount = UILabel(frame: CGRect(x: 22, y: -05, width: 20, height: 20))
badgeCount.layer.borderColor = UIColor.clear.cgColor
badgeCount.layer.borderWidth = 2
badgeCount.layer.cornerRadius = badgeCount.bounds.size.height / 2
badgeCount.textAlignment = .center
badgeCount.layer.masksToBounds = true
badgeCount.textColor = .white
badgeCount.font = badgeCount.font.withSize(12)
badgeCount.backgroundColor = .red
badgeCount.text = "4"
let rightBarButton = UIButton(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
rightBarButton.setBackgroundImage(UIImage(named: "NotificationBell"), for: .normal)
rightBarButton.addTarget(self, action: #selector(self.onBtnNotification), for: .touchUpInside)
rightBarButton.addSubview(badgeCount)
let rightBarButtomItem = UIBarButtonItem(customView: rightBarButton)
navigationItem.rightBarButtonItem = rightBarButtomItem
I had the same task. I didn't want to use third-party libraries. Firstly, I tried Stefano's solution and it's great however I decided to implement my own way to solve it.
In my humble opinion, there are simple steps described below briefly:
Create UIView instance within .xib file and put necessary items like UILabel or UIImageView instance depending on your design requirements.
The final action I did in this step is putting invisible button in the top of view's hierarchy.
Create YourCustomView.swift and link all #IBOutlets from xib to current file inside your custom view class implementation.
Next, implement class function in YourCustomView class which will load custom view from xib and return it as YourCustomView instance.
Finally, add your custom badge to your custom view controller instance!
My result is..
P.S. If you need to implement #IBActions I recommend to link your custom view and custom view controller through the delegate pattern.
using M13BadgeView.. use this code
(im using fontawesome.swift for buttons :: https://github.com/thii/FontAwesome.swift)
let rightButton = UIButton(frame: CGRect(x:0,y:0,width:30,height:30))
rightButton.titleLabel?.font = UIFont.fontAwesome(ofSize: 22)
rightButton.setTitle(String.fontAwesomeIcon(name: .shoppingBasket), for: .normal)
let rightButtonItem : UIBarButtonItem = UIBarButtonItem(customView: rightButton)
let badgeView = M13BadgeView()
badgeView.text = "1"
badgeView.textColor = UIColor.white
badgeView.badgeBackgroundColor = UIColor.red
badgeView.borderWidth = 1.0
badgeView.borderColor = UIColor.white
badgeView.horizontalAlignment = M13BadgeViewHorizontalAlignmentLeft
badgeView.verticalAlignment = M13BadgeViewVerticalAlignmentTop
badgeView.hidesWhenZero = true
rightButton.addSubview(badgeView)
self.navigationItem.rightBarButtonItem = rightButtonItem
Good answer #Julio Bailon (https://stackoverflow.com/a/45948819/1898973)!
Here is the author's site with full explanation: http://www.stefanovettor.com/2016/04/30/adding-badge-uibarbuttonitem/.
It seems not to be working on iOS 11, maybe because the script try to access the "view" property of the UIBarButtonItem. I made it work:
By creating a UIButton and then creating the UIBarButtonItem using the UIButton as a customView:
navigationItem.rightBarButtonItem = UIBarButtonItem.init(
customView: shoppingCartButton)
By replacing the line in the UIBarButtonItem extension:
guard let view = self.value(forKey: "view") as? UIView else { return }
with the following:
guard let view = self.customView else { return }
Seems elegant to me and, best of all, it worked!
You can set below constraints to UILabel with respect to UIButton
align UILabel's top and trailing to UIButton
And when you need to show badge set text to UILabel and when you don't want to show badge then set empty string to UILabel
Download This
For BarButtonItem : Drag and Drop UIBarButtonItem+Badge.h and UIBarButtonItem+Badge.m class in project.
Write this code for set Badges:
self.navigationItem.rightBarButtonItem.badgeValue = "2"
self.navigationItem.rightBarButtonItem.badgeBGColor = UIColor.black
For UIButtton : Drag and Drop UIButton+Badge.h and UIButton+Badge.m class in project.
self.notificationBtn.badgeValue = "2"
self.notificationBtn.badgeBGColor = UIColor.black
Answer with extension from Julio will not work.
Starting from iOS 11 this code will not work cause line of code below will not cast UIView. Also it's counting as private API and seems to be will not pass AppStore review.
guard let view = self.value(forKey: "view") as? UIView else { return }
Thread on Apple Developer Forum
Second thing that this snippet always draws circle, so it can't fit numbers bigger than 9.
Here the simplified version by using custom view
Easy and clear solution if you are looking for only adding the red dot without the number;
private var handle: UInt8 = 0;
extension UIBarButtonItem {
private var badgeLayer: CAShapeLayer? {
if let b: AnyObject = objc_getAssociatedObject(self, &handle) as AnyObject? {
return b as? CAShapeLayer
} else {
return nil
}
}
func setBadge(offset: CGPoint = .zero, color: UIColor = .red, filled: Bool = true, fontSize: CGFloat = 11) {
badgeLayer?.removeFromSuperlayer()
guard let view = self.value(forKey: "view") as? UIView else {
return
}
var font = UIFont.systemFont(ofSize: fontSize)
if #available(iOS 9.0, *) {
font = UIFont.monospacedDigitSystemFont(ofSize: fontSize, weight: .regular)
}
//Size of the dot
let badgeSize = UILabel(frame: CGRect(x: 22, y: -05, width: 10, height: 10))
// initialize Badge
let badge = CAShapeLayer()
let height = badgeSize.height
let width = badgeSize.width
// x position is offset from right-hand side
let x = view.frame.width + offset.x - 17
let y = view.frame.height + offset.y - 34
let badgeFrame = CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: width, height: height))
badge.drawRoundedRect(rect: badgeFrame, andColor: color, filled: filled)
view.layer.addSublayer(badge)
// initialiaze Badge's label
let label = CATextLayer()
label.alignmentMode = .center
label.font = font
label.fontSize = font.pointSize
label.frame = badgeFrame
label.foregroundColor = filled ? UIColor.white.cgColor : color.cgColor
label.backgroundColor = UIColor.clear.cgColor
label.contentsScale = UIScreen.main.scale
badge.addSublayer(label)
// save Badge as UIBarButtonItem property
objc_setAssociatedObject(self, &handle, badge, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// bring layer to front
badge.zPosition = 1_000
}
private func removeBadge() {
badgeLayer?.removeFromSuperlayer()
}
}
// MARK: - Utilities
extension CAShapeLayer {
func drawRoundedRect(rect: CGRect, andColor color: UIColor, filled: Bool) {
fillColor = filled ? color.cgColor : UIColor.white.cgColor
strokeColor = color.cgColor
path = UIBezierPath(roundedRect: rect, cornerRadius: 7).cgPath
}
}
The source of the code:
https://gist.github.com/freedom27/c709923b163e26405f62b799437243f4
I only made a few changes to eliminate the number.
The MIBadgeButton-Swift is working also on UIBarButtonItems.
Here is my code after the navigation bar is created:
let rightBarButtons = self.navigationItem.rightBarButtonItems
let alarmsBarButton = rightBarButtons?.last
let alarmsButton = alarmsBarButton.customView as! MIBadgeButton?
alarmsButton.badgeString = "10"
You can do it programmatically with
self.tabBarItem.badgeColor = .red
or use the storyboard. See:

Generate random questions in swift

Can anyone help? I have a true or false game, however, I want the questions to be shuffled/random. I know there is previous shuffle answers but I can't get my head around it. For example, the questions in the append section should appear at random. I have been trying different things for days. I had a look at arc4random but I had a hard time implementing it. I don't want to be spoon fed but a decent answer is all I am looking for.
Here is my swift code
// ViewController.swift
// TrueOrFalse
//
//
//
import UIKit
class ViewController: UIViewController {
// Classes
class newLabel:UILabel {
convenience required init(width:CGFloat, height:CGFloat, framewidth: CGFloat, frameheight: CGFloat) {
self.init(frame: CGRectMake(0, 0, framewidth, frameheight))
self.center = CGPointMake(width, height)
self.font = UIFont(name: "HelveticaNeue-Medium", size: 18)
}
}
class newButton:UIButton {
var button:UIButton!
convenience required init(width:CGFloat, height:CGFloat, framewidth: CGFloat, frameheight: CGFloat) {
self.init(frame: CGRectMake(0, 0, framewidth, frameheight))
self.button = UIButton.buttonWithType(UIButtonType.System) as UIButton
self.center = CGPointMake(width, height)
}
}
let width:CGFloat = UIScreen.mainScreen().bounds.width
let height:CGFloat = UIScreen.mainScreen().bounds.height
var model:ToFModel = ToFModel()
var statement:UILabel!
var correctCount:newLabel!
var incorrectCount:newLabel!
var timerCount:newLabel!
var correctAmt:Int = 0
var incorrectAmt:Int = 0
var buttonTrue:newButton!
var buttonFalse:newButton!
var count:Int = 0
var counter:Int = 60
var answer:String!
var wall:UIView!
var lastBool:String!
var displayLastBool:newLabel!
var questionNumber:newLabel!
var frame:UIImageView!
var image:UIImage!
var splashImage:UIImage!
var splashLandingText:UILabel!
var splashButtonStart:newButton!
var timer = NSTimer()
var userDefaults = NSUserDefaults.standardUserDefaults()
func nextIter() {
statement.text = model.statements[count][0]
answer = model.statements[count][1]
questionNumber.text = "Question- \(count+1)/\(model.statements.count)"
if count == model.statements.count-1{
statement.textColor = UIColor.redColor()
}
else{
statement.textColor = UIColor.blackColor()
}
if count > 0 && count < model.statements.count {
// displayLastBool.text = ""
view.addSubview(displayLastBool)
}
else {
displayLastBool.text = ""
}
count += 1
}
// View functions
func start(sender:newButton) {
count = 0
frame.image = image
displayLastBool = newLabel(width: 170, height: height*0.27, framewidth: 200, frameheight: 50)
//Timer
timer = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("updateCounter"), userInfo: nil, repeats: true)
// Put the image into the frame
// Remove current stuff
splashButtonStart.removeFromSuperview()
splashLandingText.removeFromSuperview()
// Add stuff to view
view.addSubview(timerCount)
view.addSubview(correctCount)
view.addSubview(incorrectCount)
view.addSubview(statement)
view.addSubview(buttonTrue)
view.addSubview(buttonFalse)
view.addSubview(questionNumber)
nextIter()
}
func splashPage() {
count = 0
displayLastBool?.removeFromSuperview()
// Put up the wall
view.addSubview(wall)
// Hang the frame on the wall
wall.addSubview(frame)
// Put up the text
view.addSubview(splashLandingText)
// Put up the button
view.addSubview(splashButtonStart)
frame.image = splashImage
}
func reset() {
correctCount.hidden = true
incorrectCount.hidden = true
count = 0
incorrectAmt = 0
correctAmt = 0
correctCount.removeFromSuperview()
incorrectCount.removeFromSuperview()
statement.removeFromSuperview()
buttonFalse.removeFromSuperview()
buttonTrue.removeFromSuperview()
questionNumber.removeFromSuperview()
displayLastBool.removeFromSuperview()
splashPage()
}
// Boolean detection
func boolResponse(sender:newButton) {
if count == model.statements.count {
if answer == String(sender.tag) {
count = 0
correctAmt = 0
incorrectAmt = 0
correctCount.hidden = true
incorrectCount.hidden = true
displayLastBool.hidden = false
timer = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("updateCounter"), userInfo: nil, repeats: true)
}
else {
timer.invalidate()
reset()
}
}
else if answer == String(sender.tag) {
lastBool = "Correct"
displayLastBool.textColor = UIColor.greenColor()
// Correct count increments here
correctAmt += 1
}
else if answer != String(sender.tag) {
lastBool = "Incorrect"
displayLastBool.textColor = UIColor.redColor()
// Incorrect count increments here
incorrectAmt += 1
count = 9;
}
if count == model.statements.count-1 {
correctCount.hidden = false
incorrectCount.hidden = false
correctCount.text = "Correct- \(correctAmt)"
//incorrectCount.text = "Incorrect- \(incorrectAmt)"
//Saving Highscore
var highscore=userDefaults.integerForKey("highscore")
if(correctAmt>highscore)
{
userDefaults.setInteger(correctAmt, forKey: "highscore")
}
var highscoreshow=userDefaults.integerForKey("highscore")
incorrectCount.text = "High Score- \(highscoreshow)"
timer.invalidate()
counter = 60
timerCount.text = String(counter)
timerCount.textColor = UIColor.blackColor()
}
nextIter()
}
//Timer update function
func updateCounter() {
timerCount.text = String(counter--)
if counter <= 9{
timerCount.textColor = UIColor.redColor()
}else{
timerCount.textColor = UIColor.blackColor()
}
if counter == 0{
count=9
nextIter()
resetTimer()
}
}
//Timer reset function
func resetTimer() {
correctCount.hidden = false
incorrectCount.hidden = false
correctCount.text = "Correct- \(correctAmt)"
incorrectCount.text = "Incorrect- \(incorrectAmt)"
timer.invalidate()
counter = 60
timerCount.text = String(counter)
timerCount.textColor = UIColor.blackColor()
// displayLastBool.hidden = true
//questionNumber.hidden = true
}
// Make an image view that you can modify from any function in this class
var imageView:UIImageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Append
model.statementsAppend("Sneezes regularly exceed 200 mph.", bool: "0")
model.statementsAppend("Virtually all Las Vegas gambling casinos ensure that they have no clocks.", bool: "1")
model.statementsAppend("Two human lungs have a surface area of approximately 750 square feet.", bool: "1")
model.statementsAppend("The 'black box' in an airplane is colored black.", bool: "0")
model.statementsAppend("The Statue of Liberty was a gift from Germany to America.", bool: "0")
model.statementsAppend("Ozone is helpful in the trophosphere but damaging to the stratosphere.", bool: "0")
model.statementsAppend("The can opener was invented after the can.", bool: "1")
model.statementsAppend("The world's oldest tree is OVER 9000 years old.", bool:"1")
model.statementsAppend("Emus can fly.", bool: "0")
model.statementsAppend("Game Over \n Play again?", bool: "1")
// Make the wall, the frame, and the image for the frame
wall = UIView(frame: CGRectMake(0, 0, width, height))
frame = UIImageView(frame: CGRectMake(0, 0, width, height))
//Load the text
statement = UILabel(frame: CGRectMake(0, 0, 280, height))
statement.center = CGPointMake(width/2, height*0.5)
statement.textAlignment = NSTextAlignment.Center
statement.lineBreakMode = NSLineBreakMode.ByWordWrapping
statement.numberOfLines = 99
statement.font = UIFont(name: "Arial", size: 24)
splashImage = UIImage(named: "splashGradient")
image = UIImage(named: "minimalGradient")
//Load the counts
timerCount = newLabel(width: 100, height: height*0.10, framewidth:200, frameheight:100)
correctCount = newLabel(width: 159, height: height*0.15, framewidth:100, frameheight:50)
incorrectCount = newLabel(width:147, height: height*0.19, framewidth:130, frameheight:50)
questionNumber = newLabel(width: 197, height: height*0.23, framewidth: 200, frameheight: 50)
timerCount.center = CGPointMake(width/2, height*0.09)
timerCount.textAlignment = NSTextAlignment.Center
timerCount.font = UIFont(name: "AvenirNext-DemiBold", size: 40)
timerCount.text = String(counter)
correctCount.text = "Correct- \(correctAmt)"
incorrectCount.text = "High Score- \(incorrectAmt)"
incorrectCount.textColor = UIColor.greenColor()
lastBool = "Incorrect"
correctCount.hidden = true
incorrectCount.hidden = true
questionNumber.hidden = true
//Load the buttons
buttonTrue = newButton(width: 80, height: height/1.2, framewidth: 111, frameheight: 45)
buttonFalse = newButton(width: 240, height: height/1.2, framewidth: 111, frameheight: 45)
// Style of button
buttonTrue.setBackgroundImage(UIImage(named: "true"), forState: UIControlState.Normal)
buttonFalse.setBackgroundImage(UIImage(named: "false"), forState: UIControlState.Normal)
// .tag
buttonTrue.tag = 1
buttonFalse.tag = 0
// Functions if button is clicked
buttonTrue.addTarget(self, action: "boolResponse:", forControlEvents: UIControlEvents.TouchUpInside)
buttonFalse.addTarget(self, action: "boolResponse:", forControlEvents: UIControlEvents.TouchUpInside)
// Make the splash button
splashButtonStart = newButton(width: width/2, height: height*0.8, framewidth: 244, frameheight: 58)
splashButtonStart.setBackgroundImage(UIImage(named: "splashButton"), forState: UIControlState.Normal)
splashButtonStart.addTarget(self, action: "start:", forControlEvents: UIControlEvents.TouchUpInside)
// Configure the text on the splash page
splashLandingText = UILabel(frame: CGRectMake(0, 0, 280, 280))
splashLandingText.center = CGPointMake(width/2, height*0.4)
splashLandingText.textAlignment = NSTextAlignment.Center
splashLandingText.numberOfLines = 99
splashLandingText.lineBreakMode = NSLineBreakMode.ByWordWrapping
splashLandingText.font = UIFont(name: "AvenirNext-DemiBold", size: 24)
splashLandingText.text = "Impossible True or False \n \n Are you ready to start your journey?"
// Configure the statement
splashPage()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I didn't try to wade through your code. It's too much. (tldr)
Here is a general solution. You'll need to adapt it to your needs.
Create a struct that contains a question, the possible answers, and the correct answer (if they are all true/false questions you could skip the possible answers part.) Let's call it questionStruct.
Then create an array of questionStruct structures. Populate it with questions.
Copy the list of all questions into a working array of questions. Let's call it remainingQuestions
Then user arc4random_uniform to select a question at random and remove it from the remaining questions array
let index = arc4random_uniform(remainingQuestions.count)
let aQuestion = remainingQuestions.removeAtIndex(index)
When the remainingQuestions array is empty, repopulate it with the array of all questions to start over.