I have one view (DataInputContainerView) and i load that view to DataController. This is my code for load DataInputContainerView to DataController
var heightInput: CGFloat = 50
lazy var inputContainerView: DataInputContainerView = {
let dataInputContainerView = DataInputContainerView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.heightInput))
dataInputContainerView.dataController = self
return dataInputContainerView
}()
That code was work. But i want to load again, for example
#IBAction func loadAgain(sender: AnyObject) {
self.heightInput += 15
// Put here to load that view again
}
I want make height view +15 and load again
So you want code that will create multiple instances of your DataInputContainerView class?
Don't use a lazy property. That creates a single instance the first time it's called, and the returns the same instance each time thereafter.
Instead, create a function that returns a DataInputContainerView:
func makeDataInputContainerView(height: height: CGFloat) ->
DataInputContainerView {
let rect = CGRect(x: 0, y: 0, width: self.view.frame.width,
height: height)
let dataInputContainerView = DataInputContainerView(frame: rect)
dataInputContainerView.dataController = self
return dataInputContainerView
}
And then call it:
var height = 50
for (_ in 1...5) {
var newDataInputContainerView = makeDataInputContainerView(height: height)
self.view.addSubview(newDataInputContainerView)
}
Related
I'm trying to change the width of a UIView with a slider. My problem is that instead of updating the views width my code is adding new views. I don't know how to update the view with swift playgrounds.
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
var feelings01Slider: UISlider!
var feelingsWidth01 = 100
var dayFeelings01: UIView!
var dayFeelings02: UIView!
var dayFeelings03: UIView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
feelings01Slider = UISlider()
feelings01Slider.frame = CGRect(x: 62, y: 375, width: 250, height: 20)
feelings01Slider.minimumValue = 1
feelings01Slider.maximumValue = 248
feelings01Slider.value = 100
feelings01Slider.isContinuous = true
feelings01Slider.addTarget(self, action: #selector(sliderValueDidChange(sender:)), for: .valueChanged)
setUpFeelings()
view.addSubview(feelings01Slider)
}
func setUpFeelings() {
feelingsWidth01 = Int(feelings01Slider.value)
var feelingsX02 = feelingsWidth01 + 62
var feelingsWidth02 = 80
var feelingsX03 = feelingsX02 + feelingsWidth02
var feelingsWidth03 = 70
dayFeelings01 = UIView(frame: CGRect(x: 62, y: 100, width: feelingsWidth01, height: 250))
dayFeelings01.backgroundColor = .yellow
dayFeelings02 = UIView(frame: CGRect(x: feelingsX02, y: 100, width: feelingsWidth02, height: 250))
dayFeelings02.backgroundColor = .blue
dayFeelings03 = UIView(frame: CGRect(x: feelingsX03, y: 100, width: feelingsWidth03, height: 250))
dayFeelings03.backgroundColor = .red
view.addSubview(dayFeelings01)
view.addSubview(dayFeelings02)
view.addSubview(dayFeelings03)
}
#objc func sliderValueDidChange(sender:UISlider) {
feelingsWidth01 = Int(sender.value)
dayFeelings03.removeFromSuperview()
dayFeelings02.removeFromSuperview()
dayFeelings01.removeFromSuperview()
setUpFeelings()
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
I'm new to programming so excuse me if my code seems messy.
You don't need to replace the views with new, differently-sized views . You can just change their frames. Replace your slider selector action with this:
#objc func sliderValueDidChange(sender:UISlider) {
dayFeelings01.frame.size.width = CGFloat(sender.value)
}
Note: because the yellow view was added first, it is expanding underneath the other views. That's why you can't see it get wider. Try changing the order so it's added last and you'll see it. If you want the other views to adjust to the available space, you can update their frames too, a UIStackView might make that easy.
Good luck!
I am using some cocoa pods frame to make UICollectionView. I am able to get the right data for each cell and setup views.
I want to have different ani
The animation end point should be related to the value of dataSource.The problem is that I can't use the didSet value as I wish. The frame of subviews I added are (0,0,0,0), the values of objects keep the same as initial value outside the didSet. I am not able to access the dataSource Value in setupView function.
Expected effect is that the red bar will move from left side to the right position:
class CereCell : DatasourceCell {
override var datasourceItem: Any?{
didSet {
guard let cere = datasourceItem as? CeremonyDay else { return }
nameLabel.text = cere.name
nameLabel.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
currentBar.frame = CGRect(x: 100, y: 100, width: cere.percentage*100 , height: 10)
position.x = cere.percentage
}
}
let currentBar: UIView = {
let currentBar = UIView(frame: CGRect(x: 290, y: 100, width: 300, height: 10))
currentBar.backgroundColor = .red
return currentBar
}()
override func setupViews() {
super.setupViews()
contentView.addSubview(currentBar)
let frame = currentBar.frame
print(frame)
It just print the (290, 100, 300, 10), which is not the value in didSet.
I want to make KDCircularProgressView programmatically. I included KDCircularProgressView.swift file from https://github.com/kaandedeoglu/KDCircularProgress.
Here is code form UIViewController:
private var progressView: KDCircularProgress!
private func setupProgressView(){
progressView = KDCircularProgress(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
progressView.startAngle = 90
progressView.angle = 90
progressView.trackColor = UIColor.red
progressView.progressColors = [UIColor.white]
progressView.center = view.center
}
I am calling this function in viewDidLoad, but nothing is showing on screen.
add it to main view
self.view.addSubview(progressView)
I have a relatively simple question. I created a function - covers the contents to retrieve data from the API. I need to call a function in several different classes (don't want to duplicate). I am calling that function, but nothing is getting displayed. If this function is a part of class where I want to call it, it works correctly. Where is the problem, please let me know. (I think in UIView...)? Thank you.
My function:
func loadScreen() {
var loadView:UIView!
loadView = UIView(frame: self.view.frame)
loadView!.backgroundColor = UIColor.black
loadView!.alpha = 1.0
let actView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
actView.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
actView.center = CGPoint(x: self.view.bounds.size.width / 2 , y: self.view.bounds.size.height / 2 )
actView.startAnimating()
loadView?.addSubview(actView)
self.view.addSubview(loadView!)
}
I call a function in another class in viewDidLoad (), but as I said, nothing is displayed.
First create a singleton class like this
Singleton class
import UIKit
import Foundation
class Singleton: NSObject
{
static let sharedInstance = Singleton()
override init()
{
super.init()
}
func placeBlockerView(target : UIViewController)
{
var loadView:UIView!
loadView = UIView(frame: target.view.frame)
loadView!.backgroundColor = UIColor.black
loadView!.alpha = 1.0
let actView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
actView.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
actView.center = CGPoint(x: target.view.bounds.size.width / 2 , y: target.view.bounds.size.height / 2 )
actView.startAnimating()
loadView?.addSubview(actView)
target.view.addSubview(loadView!)
}
}
After that use it from where ever you want as required
like this
Singleton.sharedInstance.placeBlockerView(target: self)
This above line will add that UIView you have created to your view controller's view.
Let me know if it don't work.
Instead of adding it in the above, it is always advised to return the UIView from that method and in your subclass of UIViewController do the following.
func viewDidLoad() {
let loadView = loadScreen()
self.view.addSubView()
}
I want to add a left/right border to my textfield. It is an IBOutlet. Also if I also add the function to style the textfield inside of the didEdit delegate callback it will update correctly.
Here is my code. Inside of ViewDidLoad.
let leftLayer = CALayer()
leftLayer.frame = CGRect(x: 0, y: 0, width: 1, height: (password.frame.size.height - 1))
leftLayer.backgroundColor = UIColor.gray.cgColor
let rightLayer = CALayer()
rightLayer.frame = CGRect(x: password.frame.size.width - 1, y: 0, width: 1, height: (password.frame.size.height - 1))
rightLayer.backgroundColor = UIColor.gray.cgColor
password.layer.setNeedsDisplay()
password.layer.addSublayer(leftLayer)
password.layer.display()
password.layer.setNeedsDisplay()
password.layer.addSublayer(rightLayer)
password.layer.display()
I've taken out all code except
let rightLayer = CALayer()
rightLayer.frame = CGRect(x: password.frame.size.width - 1, y: 0, width: 1, height: (password.frame.size.height - 1))
rightLayer.backgroundColor = UIColor.gray.cgColor
password.layer.setNeedsDisplay()
password.layer.addSublayer(rightLayer)
password.layer.display()
But iOS simply will not add this layer. I tried the snippet below
var once = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if once {
styleTextViews()
once = false
}
}
The only thing that does work is if I call it from
func textFieldDidBeginEditing(_ textField: UITextField) {
styleTextViews()
}
Then it adds it just fine..
Your problem is in ViewDidLoad you need to set this code inside viewDidLayoutSubviews because it contains the correct frame
var once = true // as the function runs multiple times
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if once {
// here
once = false
}
}