Extract the background colour of a UIImageview in an array - arrays

I want to determine the background colour of an imageview when it is tapped and perform an action based on the colour. I cannot fathom the syntax for getting the information from the array in which the imageviews are stored. I have tried the below but it says the stated error. Any help would be appreciated. I am new and I'm sorry if I'm wasting peoples time, I'm learning by making my own app and its throwing up a lot of questions. Kind regards.
'Value of type [UIImageView] has no member backgroundColour.
#IBAction func onTapping() {
if squares.backgroundColor == UIColor.red {
// code
}
}

First you need to set userIteractionEnable on all your UIImageViews
Next change your method signature to:
#IBAction func onTapping(_ sender: UITapGestureRecognizer) {
Then you will need to know which image view you are tapping on by checking the sender view property:
#IBAction func onTapping(_ sender: UITapGestureRecognizer) {
let systemRed = UIView()
systemRed.backgroundColor = .systemRed
if sender.view?.backgroundColor == systemRed.backgroundColor {
print("systemRed")
} else {
print("systemYellow")
}
}

Related

Refresh Custom Table View when coming back to its View Controller

I want to refresh my Table View after inserting data in it.
So what I'm doing is I click a button, the buttons opens another View Controller where I insert the data then press a button to add that data to an array(Object) and then It goes back to the Table View Controller, and here I want to swipe to refresh my Table View.
Here is my code:
ViewController.swift
AddProcessador.swift
I'm not exactly sure what you mean by refreshing your table view by swiping.
But I have two ideas that might work for you.
If you have only these two view controllers and you accept that the table view is also reloaded, for example, right at startup (first call of viewDidLoad), this would be a possibility:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
If you want to refresh the table view only after saving the entries, you could also create a protocol and use it.
// Create the protocol
protocol ReloaderDelegate {
func reloadTableView()
}
// Set up a variable in your AddProcessador view controller
var delegate: ReloaderDelegate?
// Set the delegate to a value when you create the AddProcessador instance in the ViewController
controller = self
// Now you can call the function in your AddProcessador view controller
delegate?.reloadTableView()
As a complete code:
protocol ReloaderDelegate {
func reloadTableView()
}
class AddProcessador: UIViewController {
var delegate: ReloaderDelegate?
// Your IBOutlets
override func viewDidLoad() {
super.viewDidLoad()
// ...
}
#IBAction func addClick(_ sender: Any) {
// 1. Add your new processador
// 2. Reload your table view
delegate?.reloadTableView()
// 3. Go back
navigationController?.popViewController(animated: true)
}
}
class ViewController: UIViewController, ReloaderDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// ...
}
func reloadTableView() {
self.tableView.reloadData()
}
#IBAction func pushAddProcessador() {
let controller = AddProcessador()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)
}
}
Please excuse me if I have made a mistake somewhere.
I hope I could help you with this somehow.
override func viewDidLoad() {
super.viewDidLoad()
refreshControl?.addAction(UIAction(handler: { _ in
DispatchQueue.main.async {
self.tableView.reloadData()
}
}), for: .primaryActionTriggered)
}
override func numberOfSections(in tableView: UITableView) -> Int {
refreshControl?.endRefreshing() //this can be moved to number of rows in section as well. We just need to tell the control we have data and to stop spinning.
return 1
}

How can i pass Label from viewController to another one without using segue?

Hi im new in swift and im trying to build a store application, i already build it but i have a problem with only one thing which is , i want to pass the data ( label, image, price label ) to another viewController without using segue. I tried all the method ( delegate, notificationCenter, closure ) but i didn't solve it.
this is a picture for new project i create it to explain what i want to do exactly .
i hope i get the solution because i search alot for it maybe for months but i didn't solve my problem :(
this is my code
passingViewController
import UIKit
extension passingDataViewController : textDelegate {
func sendText(withText: String) {
Label.text = withText
}
}
class receivingDataViewController: UIViewController {
#IBOutlet var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
receivingDataViewController
import UIKit
extension passingDataViewController : textDelegate {
func sendText(withText: String) {
Label.text = withText
}
}
class receivingDataViewController: UIViewController {
#IBOutlet var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
You didn't explain how you're creating the new controllers, but here's a simple example that just uses a tab controller. This makes use of a shared singleton to pass around the delegate, but if you're creating each controller programatically, you could update the delegate when you create each new instance.
For this example, I have created a singleton that contains the delegate
import Foundation
class SharedSingleton : NSObject
{
var updateDelegate : UpdateDelegate?
static let sharedInstance = SharedSingleton()
}
And then we define the protocol you're using.
In the passing view, you can define it like this
protocol UpdateDelegate
{
func updateDisplay(text : String)
}
and you use it (in the passing view like this
var sharedInstance = SharedSingleton.sharedInstance
#IBAction func cmdGo(_ sender: Any) {
sharedInstance.updateDelegate!.updateDisplay(text: txtInput.text!)
}
You define the receiving view to use the update protocol
class ReceivingViewController: UIViewController, UpdateDelegate {
and set up the delegate
var sharedInstance = SharedSingleton.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// setup the delegate through the shared instance
sharedInstance.updateDelegate = self
}
and then implement the update method
func updateDisplay(text: String) {
lblDisplay.text = text
}
That's it. You may need to update your implementation to change how you share the delegate pointer, but that's the process.

Updating array value using find object in the background is swift

I'm trying to retrieve data from Parse using findObjectsInbackground and store it in an array. I've already created outside the scoop of viewDidLoad().
I managed retrieving and printing the data, but they are not stored in the array and it keeps being empty!
I used self.articalsTableView.reloadData() but unfortunately the array myArray is still empty.
Any help please, this has been confusing me for two days!
import UIKit
import Parse
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var articalsTableView: UITableView!
var myArray = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
let query = PFQuery(className: "Gateshead")
query.findObjectsInBackground {(objects, error) -> Void in
if error != nil {
print(error)
} else {
if let articals = objects {
for artical in articals {
// print (articles) THIS IS WOKING WELL
self.myArray.append(artical)
self.articalsTableView.reloadData()
}
}
}
}
}
}
findObjectsInback is using a background thread and you should dispatch to mainThread whenever if you want to access UIKit stuff in this case updating self.articalsTableView.
Also self.articalsTableView.reloadData() should be called at the end (not in the loop). This to prevent a race condition on self.myArray being accessed by the main-thread (to update self.articalsTableView ) and by the background-thread (to append artical)
for artical in articals {
// print (articles) THIS IS WOKING WELL
self.myArray.append(artical)
}
DispatchQueue.main.async {
self.articalsTableView.reloadData()
}

ARKit – Add a "SCNNode" to an "ARAnchor"

I'm not sure I am approaching this correctly. I have a long rectangular box that I want to add -1.5 from the camera when the app starts up. But I want it to be stationary, like the ship that comes default in an ARKit project. But whenever I add it, the object stays relative (distance wise) to the camera. i.e - move towards it, it moves back, move back, it moves forward.
I though dropping an anchor on the scene would resolve this but I am still getting the same affect. Here is my code. Any help would be appreciated:
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
//sceneView.showsStatistics = true
// Create a new scene
let scene = SCNScene()//
// Set the scene to the view
sceneView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
//configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
print(#function, sceneView.session.currentFrame)
}
// MARK: - SCNSceneRendererDelegate
func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
print(#function, sceneView.session.currentFrame)
if !hasPortalAnchor {
//add anchor - this may take a second as the current frames are initially nil
if let currentFrame = sceneView.session.currentFrame {
var translation = matrix_identity_float4x4
translation.columns.3.z = -1.3
let transform = simd_mul(currentFrame.camera.transform, translation)
if (arrAnchors.count < 1) {
let portalAnchor = ARAnchor(transform: transform)
sceneView.session.add(anchor: portalAnchor)
arrAnchors.append(portalAnchor)
print(arrAnchors)
}
}
} else {
hasPortalAnchor = true
}
}
//this function gets called whenever we add an anchor to our scene
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let portalScene = SCNScene(named: "art.scnassets/portal.scn")!
return portalScene.rootNode.childNode(withName: "portal", recursively: true)
}
Are you deliberately using the renderer(_:) function? If not then you can just use the following viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
let scene = SCNScene(named: "art.scnassets/portal.scn")!
sceneView.scene = scene
}
This will replace the default rocket that appears on startup, with your portal scene. (Note that the scene may move around if tracking hasn't been established. For instance if the light is low, or if you are in an environment without many features (a blank or repetitive wall for instance)).
Also it looks like you're not actually setting hasPortalAnchor to true? Is it being set somewhere else?

Swift error Trying to Pass Array to Another Class

So I am probably doing this all wrong but I want to make a shopping list app and I have two view controllers, one with the list and one with a textbook and button to add to the list but I can't figure out how to get the array to the other class. I have this code so far and the error I get is
Instance member 'list' cannot be used in type 'mainViewController'
And this is my code
import UIKit
class mainViewController: UIViewController {
var list:[String] = [""]
#IBOutlet weak var item: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
// Do any additional setup after loading the view.
}
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mainViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard() {
view.endEditing(true)
}
#IBAction func AddToList(sender: UIButton) {
list.append(item.text!)
}
static func getList(inout Array: [String]) -> [String] {
return list
}
}
Any help much appreciated, please keep it positive though and keep in mind I am very new to this forum and swift. Thanks!
The error message is very clear that you are trying to access an instance field in type context (without instance).
To fix it, just remove static in getList function.
PS: Please follow Swift naming conventions to capitalize your class name

Resources