How can I add Cell index path as Index next to the Collectionview cell? - ios

I have collection view (If the process is easier on a table view I can change it to that).
I need to display the index path of the Cell just before displaying the collection view cell.
I have been trying to figure out how to work on this, here are the things I worked out (Nothing has been a good solution).
Firstly, I tried using a Collection view cell with an added Label (For numbering) and UIView (For showing the content next to it). But the shadow code is not working for the UIView on the collection view cell.
#objc extension CALayer {
func applySketchShadow(
color: UIColor = .black,
alpha: Float = 0.5,
x: CGFloat = 0,
y: CGFloat = 2,
blur: CGFloat = 4,
spread: CGFloat = 0)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2.0
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}
}
#objc extension UIView{
func applyShadowToView(){
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor.clear.cgColor
self.layer.masksToBounds = true
self.layer.masksToBounds = false
self.layer.applySketchShadow(color: UIColor.black, alpha: 0.09, x: 3, y: 2, blur: 50, spread: 4)
}}
For some weird reasons, my shadow view is not showing up. I tried various codes from online just to be sure, nothing works out.
Other things I thought off are having a header view to show the number of the Collection view, but header view needs to be as wide as Frame so this is not an option and
the other thing is having 2 collection view cells, even cells showing the Number and odd cells showing content.
But the problem with this is I want to add rearranging functionality later on and this method will not work when I want to do it.

Related

Shadow inside table view cell not working

The shadow in my cell is not working at all.
This is one of the view that I want to add shadow but it's not working. I added this code inside my custom cell class.
super.layoutSubviews()
UIview1.layer.cornerRadius = 7
UIview1.layer.borderWidth = 1.0
UIview1.layer.borderColor = HexColor.hexStringToUIColor(hex: "FA2537").cgColor
UIview1.layer.masksToBounds = true
UIview1.layer.shadowColor = HexColor.hexStringToUIColor(hex: "01A4B7").cgColor
UIview1.layer.shadowOpacity = 0.5
UIview1.layer.shadowOffset = CGSize.zero
UIview1.layer.shadowRadius = 5
}
For showing shadow on a view, you need to set its layer's masksToBounds property false.
or you can try this.
You can make a method like this and can use:
extension UIView {
func setShadowWith(color: UIColor = UIColor.black, shadowOpacity: Float = 0.2, radius: Float = 1.0, shadowOffSet: CGSize = CGSize(width: 0, height: 1)) {
self.layer.shadowColor = color.cgColor
self.layer.shadowOpacity = shadowOpacity
self.layer.shadowOffset = shadowOffSet
self.layer.shadowRadius = CGFloat(radius)
}
}
and can use function like:
yourContainerView.setShadowWith()
Here parameters used in functions are taking default values. you can change accordingly.
Set maskToBounds to false instead of true:
UIview1.layer.masksToBounds = false

How can i drop shadow to top and bottom of view which is inside the table view cell?

I have a view inside the table view cell and I want to show shadow to that view if below situations
if view on first cell then drop shadow to top, left, right.
if view on last cell then drop shadow to bottm, left, right.
other wise drop shadow only on left and right.
Thank You.
yourView.layer.shadowColor = UIColor.black.cgColor
yourView.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
yourView.layer.shadowOpacity = 0.5
yourView.layer.shadowRadius = 2.0
And adapt the code below to the way you want for the corners that you'd like to drop shadow.
var shadowRect: CGRect = yourView.bounds.insetBy(dx: 0, dy: 4) // inset top and bottom of the cell
yourView.layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath
put this code in your class
extension UIView {
func dropShadow(scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.2
layer.shadowOffset = CGSize.zero
layer.shadowRadius = 5
}}
Then call it:--
YourView.dropShadow(scale: true)

UICollectionViewCell doesn't draw shadow when zoomed if at the sides of the collection

I'm having a funny issue working on my first tvOS application (actually my first iOS application in general since years).
What I want to achieve is to have a custom zoom and shadow for the cells of my UICollectionView when they are selected.
The weird thing is I'm able to see the zoom effect and the shadow for the cells, but when these are at both sides of the collection, the shadow is not rendered.
Let me show you the issue with few images.
This is the correct result I'd like to achieve and it works fine for "internal" cells: bigger shadow + zoom (scale).
This is the wrong result I'm getting for "external" cells: zoom (scale) is ok, but the shadow is not updated. This is also valid for the other "external" cell on the right side of the collection.
Further funny thing is, if I do not scale the cells, then the shadow is correctly update:
This is the code of my custom UICollectionViewCell:
import UIKit
class MyCloudCollectionViewCell: UICollectionViewCell {
var selectTrans: UIFocusAnimationCoordinator?
var scale : CGFloat = 0.0
override func layoutSubviews() {
super.layoutSubviews()
self.clipsToBounds = false
self.layer.masksToBounds = false
self.layer.shadowOpacity = 0.20;
self.layer.shadowRadius = 4.0;
self.layer.shadowOffset = CGSize(width: 1, height: 6);
self.scale = 1.0
}
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
coordinator.addCoordinatedAnimations({
super.didUpdateFocus(in: context, with: coordinator)
if self.isFocused {
self.layer.shadowOpacity = 0.25;
self.layer.shadowRadius = 4.0;
self.layer.shadowOffset = CGSize(width: 1, height: 18);
self.scale = 1.19
let transform = CGAffineTransform(scaleX: self.scale, y: self.scale)
self.layer.setAffineTransform(transform)
} else {
self.layer.shadowOpacity = 0.20;
self.layer.shadowRadius = 4.0;
self.layer.shadowOffset = CGSize(width: 1, height: 6);
self.scale = 1.0
let transform = CGAffineTransform(scaleX: self.scale, y: self.scale)
self.layer.setAffineTransform(transform)
}
}, completion: nil)
}
}
Collection also have these settings:
self.collectionView?.clipsToBounds = false
self.collectionView?.layer.masksToBounds = false
The problem is that the base view cell is not the right place to perform that kind of operation.
Try to use a custom container view instead of the base view cell.

Why is my table view shadow scrolling with my table view?

I added shadow to my table view but unfortunately when I scroll through the table view the shadow also moves with the table. The code for adding shadow is as follows:
func addShadow(to myView: UIView){
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: uiView.frame.width, height: uiView.frame.height * 1.1))
uiView.layer.shadowColor = UIColor.black.cgColor
uiView.layer.shadowOffset = CGSize(width: 0.2, height: 0)
uiView.layer.shadowOpacity = 0.5
uiView.layer.shadowRadius = 5.0
uiView.layer.masksToBounds = false
uiView.layer.shadowPath = shadowPath.cgPath
}
Can you please explain to me why is this happening and how to make the shadow stick to its designated location?
Thank you in advance.
If you are adding shadow on tableView, it will scroll along with tableview data. To prevent that you have to add UIView first. Add tableview on that view. Add shadow for the UIView you have taken. It will stick to designated location.
This is my solution in Swift 3 with an UIView and a CAGradientLayer inside.
override func viewWillAppear(_ animated: Bool) {
addShadow(myView: myTab)
}
func addShadow(myView: UIView){
let shadowView = UIView()
shadowView.center = CGPoint(x: myView.frame.minX,y:myView.frame.minY - 15)
shadowView.frame.size = CGSize(width: myView.frame.width, height: 15)
let gradient = CAGradientLayer()
gradient.frame.size = shadowView.frame.size
let stopColor = UIColor.clear.cgColor
let startColor = UIColor.black.withAlphaComponent(0.8).cgColor
gradient.colors = [stopColor,startColor]
gradient.locations = [0.0,1.0]
shadowView.layer.addSublayer(gradient)
view.addSubview(shadowView)
}

Swift: Producing a circle UIView is giving a diamond like shape

I created an extension on UIView so that I can create circle views easily without writing the code in each custom component. My code looks as:
extension UIView {
func createCircleView(targetView: UIView) {
let square = CGSize(width: min(targetView.frame.width, targetView.frame.height), height: min(targetView.frame.width, targetView.frame.height))
targetView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: square)
targetView.layer.cornerRadius = square.width / 2.0
}
}
the purpose of the property square is to always compute a perfect square based on the smallest property of width or height from the target view, this stops rectangles from trying to become squares, as that could obviously never produce a circle.
Inside my custom component I call this method with:
// machineCircle is a child view of my cell
#IBOutlet weak var machineCircle: UIView!
// Whenever data is set, update the cell with an observer
var machineData: MachineData? {
didSet {
createCircleView(machineCircle)
}
}
The problem I am having is that my circles are rendering to the screen like this:
When debugging, I inspected the square variable, it consistently prints width: 95, height: 95, which would lead me to believe that a perfect circle should be rendered each time.
Why am I seeing these strange shapes?
UPDATE I have found why perfect circles aren't being formed but I am not sure how to go about it.
In my storyboard I set the default size of my machineCircle view to be 95x95, however when my view loads, the collection cells width and height are computed dynamically with this method:
override func viewDidLoad() {
super.viewDidLoad()
let width = CGRectGetWidth(collectionView!.frame) / 3
let layout = collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width + width / 2)
}
This resizes the collection view cells so that they can fit in cols of 3 accross the screen, but it does not seem to change the base scale of the inner machineCircle view. The machineCircle view still retains its size of 95x95 but seems to scale down inside the view causing the effect to be caused (thats what I have observed thus far). Any ideas?
Taking Matt's advice, I created a method to draw a circle within a UIView using CALayers.
For any who are interested, here is my implementation:
func drawCircleInView(parentView: UIView, targetView: UIView, color: UIColor, diameter: CGFloat)
{
let square = CGSize(width: min(parentView.bounds.width, parentView.bounds.height), height: min(parentView.bounds.width, parentView.bounds.height))
let center = CGPointMake(square.width / 2 - diameter, square.height / 2 - diameter)
let circlePath = UIBezierPath(arcCenter: center, radius: CGFloat(diameter), startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
print(targetView.center)
shapeLayer.path = circlePath.CGPath
shapeLayer.fillColor = color.CGColor
shapeLayer.strokeColor = color.CGColor
shapeLayer.lineWidth = 1.0
targetView.backgroundColor = UIColor.clearColor()
targetView.layer.addSublayer(shapeLayer)
}
And it is called with:
drawCircleInView(self, machineCircle, color: UIColor.redColor(), radius: 30)
Here is the result:
The white box behind is for demonstration purposes only, it shows the parent view that the circle is drawn into, this will be set to transparent in production.

Resources