Xcode how to combine UI buttons? - ios

i'm making a custom keyboard and wanna add shadow to buttons.
so added some code(keys.layer~~) in viewDidLoad()
but i can't set multiple button to one IBOutlet
what i want is all keys have 'keys(IBOutlet)' as value(?)
is it possible? if it's not, any other thing is fine :)
help!
this is my code (pls ignore next keyboard button)
#IBAction func keys(sender: AnyObject) {
}
#IBOutlet weak var keys: UIButton!
#IBOutlet var nextKeyboardButton: UIButton!
override func updateViewConstraints() {
super.updateViewConstraints()
// Add custom view sizing constraints here
}
override func viewDidLoad() {
super.viewDidLoad()
loadInterface()
keys.layer.cornerRadius = 4.0;
keys.layer.shadowColor = UIColor.blackColor().CGColor
keys.layer.shadowOffset = CGSizeMake(0.0, 2.0)
keys.layer.masksToBounds = false
keys.layer.shadowRadius = 1.0
keys.layer.shadowOpacity = 0.5

You can make UIButton extension like this and used with all the object of your custom keyboard Button
extension UIButton {
func setShadow() {
self.layer.cornerRadius = 4.0;
self.layer.shadowColor = UIColor.blackColor().CGColor
self.layer.shadowOffset = CGSizeMake(0.0, 2.0)
self.layer.masksToBounds = false
self.layer.shadowRadius = 1.0
self.layer.shadowOpacity = 0.5
}
}
Now you can call this method with your button object like this way
self.nextKeyboardButton.setShadow()
Edit:
If you want to access multiple Button object with same object you can create an Array of UIButton, and store all the Outlet Button inside that array.
var buttonArray = [UIButton]()

Related

Changing class in a UIView (Swift)

I would like to use a button to toggle the contents of a UIView.
I set up two classes, graphClass1 and graphClass2. (The button is in the topView.)
When I click the button, I get the "my button" message from debugPrint, but I don't get the debugPrint messages from within the classes. So, I added setNeedsDisplay but that did not help.
(This is a simplified version - there are actually a lot more classes - which is why I am trying to reuse the same view instead of just creating two separate views.)
how do I get the appropriate class to display in the view?
because graphClass1 creates additional subviews when I toggle back and forth, will the number of graphClass1's subviews just keep growing? If so, how do I remove them when leaving? (I know that self.layer.sublayers = nil or textView.removeAll() would leave them until returning - if they even remove them at all.)
in the button toggle, rather than use a Bool to test which graph, I'd prefer something more intuitive like if currentGraph == GraphClass1 but this gives me the error message: Binary operator '==' cannot be applied to operands of type 'UIView' and 'GraphClass1.Type'. How would do I fix this?
class ViewController: UIViewController {
#IBOutlet var topView: UIView!
#IBOutlet var bottomView: UIView!
#IBOutlet var myButton: UIButton!
var graph1: Bool = true
var currentView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
bottomView = GraphClass1()
setConstraints()
}
#IBAction func myButton(_ sender: Any) {
debugPrint("my button")
if graph1 {
currentView.removeFromSuperview()
currentView = GraphClass2()
cv2.addSubview(currentView)
graph1 = false
}
else {
currentView.removeFromSuperview()
currentView = GraphClass1()
cv2.addSubview(currentView)
graph1 = true
}
cv2.setNeedsDisplay()
}
}
class GraphClass1: UIView {
var textView = UITextView()
override func draw(_ rect: CGRect) {
super.draw(rect)
self.layer.sublayers = nil
textView.removeAll()
createTextView()
debugPrint("inside GraphClass1")
}
func createTextView() {
textView = UITextView(frame: CGRect(x: 8, y: 8, width: 300, height: 100))
textView.text = "Test, this is only a test"
textView.textAlignment = .center
textView.font = UIFont(name: "Courier", size: 16)
textView.backgroundColor = .orange
self.addSubview(textView)
}
}
class GraphClass2: UIView {
override func draw(_ rect: CGRect) {
super.draw(rect)
debugPrint("inside GraphClass2")
}
}
Instead of changing the UIView() to a GraphClass(), you should add GraphClass() to bottomView() as a subview. To switch out GraphClass1(), you would remove it from bottomView() and set up GraphClass2() as the subview of bottomView(). Removing a view also removes all its subviews.
First, create a bottomView in interface builder, just like the top view. It will be like a place holder. You will have;
#IBOutlet var bottomView: UIView!
In viewDidLoad, you add the specific view as needed with
bottomView.addSubView(myInstanceOfAGraphView.view)
myInstanceOfAGraphView.didMove(toParent: bottomView)
I would create view controllers for each graph view and switch them as needed.
When you need to change, remove its view with;
myInstanceOfAGraphView.view.removeFromSuperview()

How do I get button shadow working with Swift 4.2?

I am trying to get my button to render a shadow in swift 4.2
I've followed other examples to no avail. What am I missing?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var btnHi: UIButton! // Standard button tweeked in view controller
#IBOutlet weak var btnNext: NextButton! // My custom button via class
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
btnHi.layer.cornerRadius = btnHi.frame.height / 2
btnHi.layer.borderWidth = 3.0
btnHi.layer.borderColor = UIColor.darkGray.cgColor
btnHi.layer.shadowColor = UIColor.black.cgColor
btnHi.layer.shadowOffset = CGSize(width: 0.0, height: 6.0)
btnHi.layer.shadowRadius = 8
btnHi.layer.opacity = 0.5
// btnHi.clipsToBounds = true
// btnHi.layer.masksToBounds = false
}
#IBAction func btnNext(_ sender: Any) {
btnNext.setupShakeButton()
}
}
should see a drop shadow for the button instead I get no shadow.
You are missing shadowOpacity which is zero by default. You should probably not use opacity because that makes the whole button semitransparent.
btnHi.layer.shadowColor = UIColor.black.cgColor
btnHi.layer.shadowOffset = CGSize(width: 0.0, height: 6.0)
btnHi.layer.shadowRadius = 8
btnHi.layer.shadowOpacity = 0.5
Also note that clipping has to be turned off:
btnHi.layer.masksToBounds = false

Clip button to view

enter image description hereSo i have backgroundView (UIView) and two buttons in it.
Now i have made following code
buttonBackgroundView.layer.cornerRadius = 5.0
buttonBackgroundView.layer.borderColor = UIColor.black.cgColor
buttonBackgroundView.layer.borderWidth = 0.5
#IBOutlet weak var firstbutton: UIButton!{
didSet{
proceedButton.clipsToBounds = true
}
}
in this the view has rounded corner but the button does not have those rounded corners
How do i implement that? (so that button also get the rounded corner.
I have two buttons, so I want only the left corner of left button and right corner of right button.
I have added the image link which i want to achieve.
class ViewController: UIViewController {
#IBOutlet weak var yourView: UIView! //Create your view outlet
override func viewDidLoad() {
super.viewDidLoad()
yourView.clipsToBounds = true
yourView.layer.cornerRadius = 15 // As per you requirement
yourView.layer.borderColor = UIColor.black.cgColor
yourView.layer.borderWidth = 2
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Add Following constraint
Output:
This might help you :)
Please try using masksToBounds property,
#IBOutlet weak var firstbutton: UIButton!{
didSet{
proceedButton.clipsToBounds = true
proceedButton.masksToBounds = true
}
}

Using scroll view programmatically

I am trying to develop an app with the UI created only programmatically.
I want to create a simple view which is a UIScrollView (to be able to scroll the view when the keyboard is appearing) with a containerView (UIView) where we can find a button.
I am using PureLayout to make easier the set up of constraints, swift 4, Xcode 9.2 beta
Below the class of this view
class SimpleView: UIScrollView {
var containerView: UIView!
var signInButton: UIButton!
var signInLabel: UILabel!
var screenSize: CGSize = CGSize.zero
var shouldSetupConstraints = true
override init(frame: CGRect) {
super.init(frame: frame)
self.screenSize = frame.size
self.containerView = UIView(frame: CGRect.zero)
self.signInButton = UIButton(frame: CGRect.zero)
self.signInLabel = UILabel(frame: CGRect.zero)
self.addSubview(self.containerView)
self.containerView.addSubview(self.signInButton)
self.signInButton.addSubview(self.signInLabel)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func updateConstraints() {
if(shouldSetupConstraints) {
self.layoutSignInButton()
self.layoutSignInLabel()
shouldSetupConstraints = false
}
super.updateConstraints()
}
private func layoutContainerView() {
self.containerView.autoPinEdgesToSuperviewEdges()
self.containerView.backgroundColor = UIColor.yellow
}
private func layoutSignInButton() {
self.signInButton.autoPinEdge(toSuperviewEdge: .right)
self.signInButton.autoPinEdge(toSuperviewEdge: .left)
self.signInButton.autoPinEdge(toSuperviewEdge: .top)
self.signInButton.autoSetDimension(.height, toSize: 55.0)
self.signInButton.backgroundColor = UIColor(hex: "#FD9FA2")
}
private func layoutSignInLabel() {
self.signInLabel.autoPinEdgesToSuperviewEdges()
self.signInLabel.shadowColor = UIColor(hex: "#9A615E")
self.signInLabel.shadowOffset = CGSize(width: 0.0, height: 2)
self.signInLabel.text = NSLocalizedString("SIGN IN", comment: "")
self.signInLabel.textAlignment = .center
self.signInLabel.textColor = UIColor.white
self.signInLabel.font = UIFont.boldSystemFont(ofSize: 15.0)
self.signInLabel.backgroundColor = UIColor.clear
}
}
Below the code of the UIViewController subclass embedding the previous view
class SignInViewController: UIViewController {
var simpleView: SimpleView!
override func viewDidLoad() {
super.viewDidLoad()
self.simpleView = SimpleView(frame: self.view.bounds) // with SimpleView(frame: self.view.frame) has the same behaviour
self.view.addSubview(self.simpleView)
self.simpleView.autoPinEdgesToSuperviewEdges()
self.navigationController?.navigationBar.isHidden = true
}
}
Unfortunatly the result is not the one expected : see below
What am I missing ?
Different points are missing:
- The position of the button is weird (space between the button and the top / left side of the button partly hidden outside of the screen)
- the container view is invisible (backgroundColor = UIColor.yellow has no effect)
Thank you by advance !
//////////////////////////// EDIT ////////////////////////////////
Below a screenshot of the exact same code using a UIView instead of UIScrollView
Class SimpleView: UIView {
enter image description here
The content of a UIScrollView must also define the .contentSize` of the scroll view.
I don't use PureLayout, so I don't know what the syntax is, but in your layoutContainerView() func, you need to also do:
self.containerView ... set width dimension to SuperviewWdith
That will set the content of containerView to the width of the scroll view, and that should fix the width part.
I assume you will be adding elements to containerView and set their constraints to control the height of it.

How to access the value of a UIStepper inside a Cocoa Touch Class

I'm trying to create a custom slider, using a cocoa touch class, whose maximum value is determined by a UIStepper. I have the UIStepper wired to my view controller and I want to reference its value inside the cocoa touch class as the slider's maximum value. What is the syntax for referencing the stepper's value inside the class?
I keep getting the error use of unresolved identifier.
Here is my viewController:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var stepperValue: UIStepper!
#IBOutlet weak var label: UILabel!
let slider1 = Slider1(frame: CGRectZero)
override func viewDidLoad() {
super.viewDidLoad()
label.textColor = UIColor.darkTextColor()
slider1.backgroundColor = UIColor.lightGrayColor()
view.addSubview(slider1)
}
override func viewDidLayoutSubviews() {
let margin: CGFloat = 20.0
let width = view.bounds.width - 2 * margin
slider1.frame = CGRect(x: margin, y: 3 * margin, width: width, height: 1.5 * margin)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Here is my UIControl subclass:
class Slider1: UIControl {
var minimumValue = 0.0
var maximumValue = stepperValue.value
var value = 0
let trackLayer = CALayer()
var trackHeight:CGFloat = 2.0
var trackColor = UIColor.blackColor().CGColor
var tickHeight:CGFloat = 8.0
var tickWidth: CGFloat = 2.0
var tickColor = UIColor.blackColor().CGColor
let thumbLayer = CALayer()
var thumbColor = UIColor.blackColor().CGColor
var thumbMargin:CGFloat = 2.0
var thumbWidth: CGFloat {
return CGFloat(bounds.height)
}
}
If you want a slider, use a slider. You will have a LOT of work to do if you want to create your own slider-like control starting from UIControl.
Just make your view controller drive everything.
Have the value changed event on your stepper trigger an action in the view controller.
In that stepperValueChanged action, fetch the new value of the stepper and use it to change the maximum value of the slider. That's all there is to it.

Resources