iterate through objects/variables Swift - xcode

How can I iterate through objects/variables in Swift. Can I create an array or dictionary when I have objects attached so that I don't have to write code for each button. I'm a nubie so please speak to me like I'm four. Thanks for the help in advance.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.button1.alpha = 0.0
self.button2.alpha = 0.0
self.button3.alpha = 0.0
...
}

import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
var arrayOfButtons = [UIButton]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
arrayOfButtons = [button1, button2, button3]
for button in arrayOfButtons {
button.alpha = 0.0
}
}

In addition to Tim's answer, you can also create buttons programmatically, and deal with them in your code!
override func viewDidLoad() {
for i in 1...10 {
let button = UIButton()
button.frame = CGRectMake((CGFloat(i-1)*50), 0, 50, 50)
button.targetForAction("buttonClick:", withSender: self)
button.tag = i
self.view.addSubview(button)
}
}
func buttonClick(sender:AnyObject) {
let tag = sender.tag!
//click logic here
}

Related

Passing a value from inputField to NSTextField

I'd like to pass string value from one NSTextField to another NSTextField pressing a button. I used for this for-in loop. I need to pass a value from inputField to visibleText1, then to visibleText2 and then to visibleText3. But it doesn't work.
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in (visibleText1.stringValue...visibleText3.stringValue) {
visibleText.stringValue[u] = inputField.stringValue
inputField.stringValue = ""
}
}
}
Xcode gives me an error:
// Type 'ClosedInterval<String>' does not conform to protocol 'SequenceType'
How how to do it right?
No you can't do that because you can't create a range of string values of different text fields.
You could make an array of the three fields and enumerate that:
#IBAction func applyButton(sender: AnyObject) {
for field in [visibleText1, visibleText2, visibleText3] {
field.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
or with the forEach function
#IBAction func applyButton(sender: AnyObject) {
[visibleText1, visibleText2, visibleText3].forEach {
$0.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
Resetting the inputField in the repeat loop would always apply an empty string after the first iteration.
There are several things wrong with this, but I will start with what will work:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in [visibleText1, visibleText2, visibleText3] {
u.stringValue = inputField.stringValue
}
}
}
So what's wrong with the original?
1) Your (visibleText1.stringValue...visibleText3.stringValue) is of type String ... String, which is not what you intended. You need to have an array of NSTextFields.
2) visibleText.stringValue[u] is not even a thing. There is no variable visibleString, and even if it was an NSTextField - which I think is what you want it to be, it's .stringValue is a String, and not an array.
3) What are you doing setting inputField.stringValue = "" inside the for loop? If your construct worked, only the first field would be set.
4) Not an error, but why are you doing all of this inside NSApplicationDelegate, rather than a viewController?

NSPrintOperation View Is blank

Im still new to OSX / Swift 3.1 but Im a little stumped, Ive build an epos system and its work all fine, Im just stuck with printing out the receipt.
I have build a XIB View and the corresponding swift file for it show below
class Receipt: NSView {
let currentOrder = NewOrder.instance
#IBOutlet var view: NSView!
#IBOutlet weak var facebookString: NSTextField!
#IBOutlet weak var websiteString: NSTextField!
#IBOutlet weak var totalString: NSTextField!
#IBOutlet weak var vatString: NSTextField!
#IBOutlet weak var subTotalString: NSTextField!
#IBOutlet weak var CashierName: NSTextField!
#IBOutlet weak var orderNumber: NSTextField!
#IBOutlet weak var date: NSTextField!
#IBOutlet weak var itemList: NSTextField!
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
Bundle.main.loadNibNamed("ReceiptView", owner: self, topLevelObjects: nil)
let contentFrame = NSMakeRect(0, 0, frame.size.width, frame.size.height)
self.view.frame = contentFrame
self.addSubview(self.view)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
subTotalString.stringValue = "Hello World"
view.draw(dirtyRect)
subTotalString.draw(dirtyRect)
}
}
I have added the nib name to the XIB reference and loaded a new Receipt() class and added the view to the NSPrintOperation.
let order = NewOrder.instance
let sview = Receipt()
let printer = NSPrinter(name: "EPSON TM-T88V");
let printData = NSPrintInfo()
printData.printer = printer!
let printerName = printer?.name
let docSize = NSMakeSize(CGFloat(204.0), CGFloat(200));
let res = "180x180dpi";
let speed = "Auto";
let blank = "Off";
let paperCut = "DocFeedCut";
let chashDrwr1 = "After";
let chashDrwr2 = "Off";
let buzzerControl = "Off";
let buzzerPattern = "Internal";
let buzzerRepeat = "1";
let data = TMPrintSupport.tmSetJobTicket(printData, printerName: printerName, documentSize: docSize, resolution: res, speed: speed, blank: blank, paperCut: paperCut, chashDrwr1: chashDrwr1, chashDrwr2: chashDrwr2, buzzerControl: buzzerControl, buzzerPattern: buzzerPattern, buzzerRepeat: buzzerRepeat)
let po = NSPrintOperation(view: sview.view, printInfo: printData)
// po.showsPrintPanel = false
po.canSpawnSeparateThread = true
po.cleanUp()
return po.run()
When the print view is shown it is blank and does not contain the view and is blank, I've also test printed and the print is just blank.
Any suggestions welcome, thanks

What's the correct syntax of passing an IBAction from a UICollectionViewCell to its host UIViewController?

Scenario: processing a button action originating from a UICollectionViewCell in its hosting UIViewController.
The Cell:
Here's my code:
protocol CellProtocol {
func doSomething()
}
...
class ItemCollectionCell:UICollectionViewCell {
var delegate:CellProtocol?
var itemData:ItemData?
#IBOutlet weak var descLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var imageView: UIImageView!
#IBAction func addToCartAction() {
delegate?.doSomething()
print("Add to Cart")
}
}
class ShopViewController:UIViewController, CellProtocol {
let kCellID = "ItemCell"
#IBOutlet weak var featuredItemLabel: UILabel!
#IBOutlet weak var featuredItemPriceLabel: UILabel!
#IBOutlet weak var featuredItemImageView: UIImageView!
#IBOutlet weak var collectionView: UICollectionView!
override var prefersStatusBarHidden: Bool {
return true
}
func doSomething() {
print("Howdy Batman!")
}
// -----------------------------------------------------------------------------------
// MARK: - Action Methods
#IBAction func addToCartAction(_ sender: UIButton) {
}
}
This isn't working.
I know it has something to do with delegation.
I merely sent 'self' to my custom UICollectionViewCell class during the cell-loading phase.

sending data to viewcontroller shows nil data

for some reason i cannot get the Value to send to my AddParticipant View.
Here's the Data before "ValuetoPass" and after the segue:"LAbelText"
ValuetoPass = GXEuoAkhjP
LabelText =
TableView Code for segue:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//CODE TO BE RUN ON CELL TOUCH
let indexPath = tableView.indexPathForSelectedRow!;
let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!;
let valueToPass = self.participantId[indexPath.row] as String
print("ValuetoPass = ",valueToPass)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "editParticipant") {
let viewController = segue.destinationViewController as! AddViewController
viewController.LabelText = valueToPass; }
}
}
Code for AddViewController:
#IBOutlet weak var firstnameTF: UITextField!
#IBOutlet weak var lastnameTF: UITextField!
#IBOutlet weak var gradeTF: UITextField!
#IBOutlet weak var teacherTF: UITextField!
#IBOutlet weak var emailTF: UITextField!
#IBOutlet weak var phoneTF: UITextField!
#IBOutlet weak var transportationTF: UITextField!
#IBOutlet weak var userSchoolTF: UITextField!
var LabelText = String()
#IBOutlet weak var qrCode: UIImageView!
#IBOutlet weak var userPicture: UIImageView!
override func viewDidAppear(animated: Bool) {
}
override func viewDidLoad() {
super.viewDidLoad()
print("LabelText = ", LabelText)
let currentUser = PFUser.currentUser()
currentUser!.refreshInBackgroundWithBlock { (object, error) -> Void in
// print("Refreshed")
currentUser!.fetchIfNeededInBackgroundWithBlock { (result, error) -> Void in
self.userSchoolTF.text = currentUser!.objectForKey("school") as? String
}
}
So I have the Data before it is sent, but it shows as nil after the segue?
I suppose you created segue in Storyboard, am I right?
Put your prepareForSegue function out of tableView func. Also prepareForSegue should Override. Try using code below
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if( segue.identifier == "editParticipant" ){
if let destinationVC = segue.destinationViewController as? AddViewController {
destinationVC.LabelText = valueToPass
}
}
}
Does Swift have NSString objects? Or is String the same thing?
In objective c, assigning to an object pointer is creating a reference to the previous object. When you make it weak, it doesn't add to the reference count, so if you deallocate the original pointer, you deallocate both. Strong means that it does add to the reference count, so deallocating the first will not actually deallocate the object.
If String and NSString are two different things, try making your type NSString instead, and see if it is retained.
I work in Obj-C, not Swift, and I'm not sure of the nuances between the two.

Cannot pass UIImageView between view controllers using a push segue

I'm trying to pass a UIImageView from a Master View Controller to a Detailed View Controller using a Push Segue. Everything loads fine on the Master View Controller, and I've created a push segue using the UIImageView on the Master View Controller. Here's my Master View Controller -
class TrackMasterViewController: UIViewController {
#IBOutlet weak var artistName: UILabel!
#IBOutlet weak var albumName: UILabel!
#IBOutlet weak var numberOfTracks: UILabel!
#IBOutlet weak var coverImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let firstRandomNumber = calculateRandomNumber()
artistName.text = Track(index: firstRandomNumber).artist
albumName.text = Track(index: firstRandomNumber).album
coverImage.image = Track(index: firstRandomNumber).image
numberOfTracks.text = Track(index: firstRandomNumber).track
}
It's the coverimage which is being passed. Here's my segue function -
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "trackSegue" {
let playlistDetailController = segue.destinationViewController as? TrackDetailViewController
playlistDetailController?.image = UIImage(named: coverImage)
}
}
And in my Detailed View Controller, i have the following:
class TrackDetailViewController: UIViewController {
#IBOutlet weak var albumCover: UIImageView!
var image:UIImage? = nil
override func viewDidLoad() {
super.viewDidLoad()
albumCover.image = image
// Do any additional setup after loading the view.
}
}
Any help determining what the issue is would be greatly appreciated.
Try changing inside your prepareForSegue:, instead of using:
playlistDetailController?.image = UIImage(named: coverImage)
Use:
playlistDetailController.image = coverImage.image
Good luck!

Resources