When I use this func,the animate not worked.
#IBOutlet weak var containerHeight: NSLayoutConstraint!
#IBOutlet weak var scanTopConstraint: NSLayoutConstraint!
#IBOutlet weak var scanView: UIImageView!
private func starAnimate() {
scanTopConstraint.constant = -containerHeight.constant
scanView.layoutIfNeeded() //if I delete this code, the animate will work,but it is not I want to effect
UIView.animateWithDuration(1.5) {
self.scanTopConstraint.constant = self. containerHeight.constant
UIView.setAnimationRepeatCount(MAXFLOAT)
self.scanView.layoutIfNeeded()
}
}
With this code, scanView just show the last status.
Could someone tell me why.
Thank for your reading and any help will be appreciated.
Related
These are my Outlets, how can I out all off these in an array?
#IBOutlet weak var progressBar1: UIProgressView!
#IBOutlet weak var progressBar2: UIProgressView!
#IBOutlet weak var progressBar3: UIProgressView!
#IBOutlet weak var progressBar4: UIProgressView!
Open the Assistant Editor, right-click and drag from one of your UIProgressView's or just drag from its "Referencing Outlet Collections" to the code file.
Insert outlet collection
Then you can drag from your swift file's #IBOutlet to the rest of your UIProgressView's. Add view to collection
On top declare a variable first like this
var outlets: [UIProgressView] = []
and now on ViewDidLoad method you can use this to put all outlets on that array
like this:
outlets = [progressBar1, progressBar2, progressBar3, progressBar4]
Hope you understand.
class ViewController: UIViewController {
#IBOutlet weak var p1: UIProgressView!
#IBOutlet weak var p2: UIProgressView!
#IBOutlet weak var p3: UIProgressView!
#IBOutlet weak var p4: UIProgressView!
var outlets: [UIProgressView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
outlets = [
p1,p2,p3,p4
]
}
}
If you have other types of views you can use
var outlets: [UIView] = [...]
As mentioned here Swift - IBOutletCollection equivalent you can use IBOutletCollection to do that. You can drag all your views to one IBOutlet array.
#IBOutlet weak var progressBars: [UIProgressView]!
For example, you can access the first progressBar like
progressBars[0]
But you have to careful about the order of progressBars, when you define IBOutletCollections the collection will not be order guaranteed. You can define the for each view and sort by their tags in runtime as mentioned here also Is IBOutletCollection guaranteed to be of correct order?
To order all views by their tags like
progressBars = progressBars.sorted { $0.tag < $1.tag }
I have a view controller with a few labels and switches inside of it. Is there any way to make the whole view look "scrollable" like how UITableViewCells look. Like even if there isn't enough content to need it to be scrollable I want that interactive gesture that UITableViewCells have. The whole point of this is to make all the pages on my app feel similar. Is there any way to add that same "scrolling" or "dynamic" feeling to the normal view?
Edit: A link to show what I mean
https://imgur.com/a/wJtfIKK
Here is the code where I connect the scroll view and I am making it "scrollable"
class ThemesViewController: UIViewController {
#IBOutlet weak var spacer: UIView!
#IBOutlet weak var overrideThemeDesc: UILabel!
#IBOutlet weak var overrideSystemTheme: UILabel!
#IBOutlet weak var overrideThemeToggle: UISwitch!
#IBOutlet weak var backgroundView: UIView!
#IBOutlet weak var lightButton: RadioButton!
#IBOutlet weak var darkButton: RadioButton!
#IBOutlet weak var lightText: UILabel!
#IBOutlet weak var darkText: UILabel!
#IBOutlet weak var appearanceLabel: UILabel!
#IBOutlet var interactiveView: UIScrollView!
let themeOverrideDefaults = UserDefaults.standard
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
interactiveView.alwaysBounceVertical = true
// Rest of My Code
}
And here is a picture of the storyboard with the scroll view selected (to show it has custom class UIScrollView): https://imgur.com/a/YCKPKpj
You can embed your view into a UIScrollView and then set
scrollView.alwaysBounceVertical = true
so that you get that scrolling effect even if the content is not large enough to be scrolled.
https://developer.apple.com/documentation/uikit/uiscrollview/1619383-alwaysbouncevertical
I have a horizontal uistackview and i have 5 imageviews in it. I need to get id of the imageview that is tapped. I tried adding tap gesture identifier and get sender's id, but i am not getting it.
What i have tried till now is as follows
#IBOutlet weak var userRateViewStar1ImageOutlet : UIImageView!
#IBOutlet weak var userRateViewStar2ImageOutlet : UIImageView!
#IBOutlet weak var userRateViewStar3ImageOutlet : UIImageView!
#IBOutlet weak var userRateViewStar4ImageOutlet : UIImageView!
#IBOutlet weak var userRateViewStar5ImageOutlet : UIImageView!
#IBOutlet weak var userRateViewTextAreaOutlet : UITextView!
#IBOutlet var starOutletCollectionOutlet : [UIImageView]!
#IBAction func starRatingAction(_ sender: UITapGestureRecognizer)
{
var tag = sender.view!.tag
print(tag)
}
Basically i am trying to implement rate feature.
So can someone suggest me a way to implement this?
Thanks in advance
An easier way might be to create an IBOutletCollection e.g:
//1. Create An Array Of Your ImageViews
#IBOutlet var ratingStarImageViews: [UIImageView]!
Then assign a tag and the gesture to them e.g:
//2. Assign Tags To The Them
var tag = 0
for view in ratingStarImageViews{
let ratingGesture = UITapGestureRecognizer(target: self, action: #selector(starRatingAction(_:)))
view.addGestureRecognizer(ratingGesture)
view.tag = tag
tag += 1
}
Hope it helps.
I am trying to write the following code in a shorter way.
func colourChangeIfDeletionCancelled(word:Int){
for i in 0...selectedWords[word].count - 1 {
let square = selectedWords[word][i]
arrayOfRows[square.0][square.1].topToRight.backgroundColor = nil
arrayOfRows[square.0][square.1].topToLeft.backgroundColor = nil
arrayOfRows[square.0][square.1].bottomToRight.backgroundColor = nil
arrayOfRows[square.0][square.1].bottomToLeft.backgroundColor = nil
arrayOfRows[square.0][square.1].horizontalTube.backgroundColor = nil
arrayOfRows[square.0][square.1].verticalTube.backgroundColor = nil
arrayOfRows[square.0][square.1].endFromLeft.backgroundColor = nil
arrayOfRows[square.0][square.1].endFromRight.backgroundColor = nil
arrayOfRows[square.0][square.1].endFromTop.backgroundColor = nil
arrayOfRows[square.0][square.1].endFromBottom.backgroundColor = nil
}
}
This code works but I am sure there is a better (shorter) way to do write it but I am unsure how. I have tried to make a function that takes the subviews as a variable but am lost on how to do that. I'm sure this isn't the hardest problem but I am stuck on it and any help is appreciated.
Edit:
arrayOfRows is just an array of arrays of a class I have created called LetterSquareView
class LetterSquareView: UIView {
var letter:String!
#IBOutlet weak var topToLeft: UIView!
#IBOutlet weak var topToRight: UIView!
#IBOutlet weak var bottomToRight: UIView!
#IBOutlet weak var bottomToLeft: UIView!
#IBOutlet weak var horizontalTube: UIView!
#IBOutlet weak var verticalTube: UIView!
#IBOutlet weak var endFromLeft: UIView!
#IBOutlet weak var endFromRight: UIView!
#IBOutlet weak var endFromTop: UIView!
#IBOutlet weak var endFromBottom: UIView!
#IBOutlet weak var topToLeftWhiteSpace: UIView!
#IBOutlet weak var topToRightWhiteSpace: UIView!
#IBOutlet weak var bottomToRightWhiteSpace: UIView!
#IBOutlet weak var bottomToLeftWhiteSpace: UIView!
#IBOutlet weak var letterSquareViewView: LetterSquareViewView!
#IBOutlet var letterSquareView: UIView!
#IBOutlet weak var letterLbl: UILabel!
init(frame: CGRect, letter: String) {
super.init(frame: frame)
NSBundle.mainBundle().loadNibNamed("LetterSquareView", owner: self, options: nil)
letterLbl.text = letter.capitalizedString
self.letter = letter
self.addSubview(letterSquareView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The subviews that I am trying to change the background colour of have a background colour set when they are created. I am trying to delete that colour when they are deleted. I thought there would be a function where you could input an array of the views and input a property of there's to set and it'd just be set but I can't find anything of the sort.
I guess the most straight forward way is to have:
func clearBackgroundColors(e: WhateverViewThisIs) {
for view in [e.topToRight, e.topToLeft, etc. ] {
view.backgroundColor = nil
}
}
clearBackgroundColors(arrayOfRows[square.0][square.1])
A good question to think is about responsibilities of the classes. I would argue the view in arrayOfRows[][] should have it's subviews private, knowledge of them is likely an implementation detail and not of public knowledge. So the clearBackgroundColors() method should be placed there instead of setting all colors from a more global place.
import UIKit
var arrayOfRows: [[UIView]] = [[]]
let square: (Int, Int)!
A way to make your touple code cleaner:
//extracting touple
let (row, col) = square
arrayOfRows[row][col].topToRight.backgroundColor = nil
Only use this is you are sure all the subviews of this view you want to make the background color nil.
//for all views
for arrayOfColumns in arrayOfRows {
for views in arrayOfColumns {
for subview in views.subviews {
subview.backgroundColor = nil
}
}
}
This is how I recommend to handle it. This also allows you to customize those views further with OOP design. Then you can
//with class type
//use this if there are other subviews
//make all your views in your list a CustomViewToMakeNil
class CustomViewToMakeNil: UIView {
//set the views content
}
for arrayOfColumns in arrayOfRows {
for views in arrayOfColumns {
for subview in views.subviews {
//check if they are of the type you want to make the color nil
if subview is CustomViewToMakeNil {
subview.backgroundColor = nil
}
}
}
}
I am trying to program a simple app in Xcode using Swift.
I have two labels which contain INT values which are incremented up/down by the user using Steppers as per below:
class ViewController: UIViewController {
#IBOutlet weak var valueLabel: UILabel!
#IBOutlet weak var stepper: UIStepper!
#IBAction func stepperValueChanged(sender: UIStepper) {
valueLabel.text = Int(sender.value).description
}
#IBOutlet weak var valueLabel2: UILabel!
#IBOutlet weak var stepper2: UIStepper!
#IBAction func stepperValueChanged2(sender: UIStepper) {
valueLabel2.text = Int(sender.value).description
}
I want to then have another Label (label3) which takes the INTs from label1 & label2 and divides them.
So for example if the user has Label1 as '5' and label2 as '10' I want label3 to display '0.5'.
Is there an easy way that I can do this?
As I'm sure you can tell, I'm really new to iOS development so any help or advice would be greatly appreciated!
Cheers!
Although this is a simple program you should still use best practice and adopt a model-view-controller design. Your model (data) should be separate from view (in essence the way the data is displayed). In a more 'serious' application the model would typically be a separate class, but in this case you can use local properties.
Storing data in Int properties also means you won't have to convert back from strings when you want to perform calculations.
class ViewController: UIViewController {
#IBOutlet weak var valueLabel: UILabel!
#IBOutlet weak var stepper: UIStepper!
#IBOutlet weak var valueLabel2: UILabel!
#IBOutlet weak var stepper2: UIStepper!
#IBOutlet weak var valueLabel3: UILabel!
var value1=0;
var value2=0;
#IBAction func stepperValueChanged(sender: UIStepper) {
self.value1=Int(sender.value);
self.valueLabel1.text="\(self.value1)";
self.updateResult();
}
#IBAction func stepperValueChanged2(sender: UIStepper) {
self.value2=Int(sender.value);
self.valueLabel1.text="\(self.value1)";
self.updateResult();
}
func updateResult {
if (self.value2 != 0) {
var result=Float(self.value1)/Float(self.value2)
self.valueLabel3.text="\(result)"
} else {
self.valueLabel3.text="Can't divide by 0"
}
}
}