IOS - 如何创建具有模糊背景的Facebook反应栏?

时间:2018-03-27 13:05:24

标签: ios iphone swift

虽然可能不是复制某些Facebook设计的那一周,但我希望能够设计我自己版本的反应指标视图。

enter image description here

我有三个UIImageView在与上面相同的位置排列。问题是,与Facebook不同,背景颜色可能会改变(即在UIBlurEffect之上),因此我无法将边框颜色设置为白色。

我认为设置borderColor是这样的:

imageViewOne.layer.borderColor = UIColor.clear.cgColor
imageViewOne.layer.borderWidth = 2

但是,基础imageViewTwo显示在边框而不是背景颜色。

到目前为止,我有这个:

enter image description here

会欣赏一些关于如何使这项工作的帮助/想法 - 我正在考虑面具但不确定是否。这是正确的解决方案,b。如何达到预期的效果。为了澄清,我无法将边框颜色设置为常量,因为它会随UIBlurEffect而变化。

5 个答案:

答案 0 :(得分:5)

在我看来,有两种方法可以解决您的问题。

  • WowLove创建并使用剪裁图像,如下面的Love图像。

    enter image description here

  • 另一种方法是使用mask property of UIView。创建蒙版图像并将其应用于mask属性。

    掩码图像看起来像。

    enter image description here

    应用mask的代码。

    let imvLoveMask = UIImageView.init(image: UIImage.init(named: "MASK_IMAGE_NAME"));
    imvLoveMask.frame = CGRect.init(x: 0, y: 0, width: imvLove.frame.size.width, height: imvLove.frame.size.height);
    imvLove.mask = imvLoveMask;
    

以上两种方式都可以帮助您在问题中实现您想要的效果。下图中的图标背景为UIVisualEffectView

enter image description here

在我看来,剪切图像的第一种方式更好更快,因为您不需要为imageView应用蒙版。但如果您不想出于某种原因创建剪裁图像,则可以使用第二种方式。

有关详细信息,请查看my demo repo

答案 1 :(得分:2)

您需要剪切图像的一部分,以便让图像之间的间隙中可以看到基础内容。参见游乐场样本。

将smile_1,smile_2,smile_3图片添加到游乐场资源中。我从https://emojipedia.org/facebook/获取了表情符号图片。

enter image description here

import UIKit
import PlaygroundSupport

class EmojiView: UIView {
   var imageView = UIImageView()
   var imageInset = UIEdgeInsets(top: 3.0, left: 3.0, bottom: 3.0, right: 3.0)
   var shapeLayer = CAShapeLayer()
   var overlap: CGFloat = 0.0 {
      didSet {
         self.updateShape()
      }
   }

   override init(frame: CGRect) {
      super.init(frame: frame)
      self.setup()
   }

   required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
   }

   // MARK: UIView
   override func awakeFromNib() {
      super.awakeFromNib()
      self.setup()
   }

   override func layoutSubviews() {
      super.layoutSubviews()
      self.imageView.frame = UIEdgeInsetsInsetRect(self.bounds, self.imageInset)
      self.shapeLayer.frame = self.bounds
      self.updateShape()
   }

   // MARK: Private
   private func setup() {
      self.addSubview(self.imageView)
      self.layer.mask = self.shapeLayer
   }

   private func updateShape() {
      let frame = self.bounds
      let path = UIBezierPath(rect: frame)
      // Cut off part of the image if overlap more then > 0
      if 0 < self.overlap {
         path.usesEvenOddFillRule = true
         path.append(UIBezierPath(ovalIn: CGRect(x: -frame.width + self.overlap, y: 0.0, width: frame.width, height: frame.height)).reversing())
      }
      self.shapeLayer.path = path.cgPath
   }
}

let overlap: CGFloat = 10 // Amount of pixels emojis overlap each other

// Create emoji views
let emojiView_1 = EmojiView(frame: CGRect(x: 5.0, y: 5.0, width: 40.0, height: 40.0))
emojiView_1.imageView.image = UIImage(named: "smile_1")

let emojiView_2 = EmojiView(frame: CGRect(x: emojiView_1.frame.maxX - overlap, y: 5.0, width: 40.0, height: 40.0))
emojiView_2.imageView.image = UIImage(named: "smile_2")
emojiView_2.overlap = overlap

let emojiView_3 = EmojiView(frame: CGRect(x: emojiView_2.frame.maxX - overlap, y: 5.0, width: 40.0, height: 40.0))
emojiView_3.imageView.image = UIImage(named: "smile_3")
emojiView_3.overlap = overlap

let holderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: emojiView_3.frame.maxX + 5, height: 50.0))

// Add gradient layer
let gradientLayer = CAGradientLayer()
gradientLayer.frame = holderView.bounds
gradientLayer.colors = [UIColor.red.cgColor, UIColor.green.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
holderView.layer.addSublayer(gradientLayer)

// Add emoji views
holderView.addSubview(emojiView_1)
holderView.addSubview(emojiView_2)
holderView.addSubview(emojiView_3)

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = holderView

答案 2 :(得分:0)

使用它:

self.imageViewOne.layer.cornerRadius = self.imageViewOne.layer.bounds.width/2
self.imageViewOne.layer.masksToBounds = true

答案 3 :(得分:0)

实际上,您可以将图像放在具有白色背景和圆形(设置角半径)的视图中,而不是屏蔽。然后,您可以通过设置zPosition或在视图层次结构的故事板上放置这些视图(其中包含白色背景和图像)。

我为你准备了一个小游乐场。您可以在屏幕截图中看到结果。我在containerViews中放置了一个视图,你可以使用uiimageview等。它有点难看但是解决了你的问题我想你应该决定如何使用它。

enter image description here

以下是代码,您可以将其复制并粘贴到新的游乐场并进行测试。

import UIKit
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

var mainContainerView = UIView(frame: CGRect(x: 0, y: 0, width: 140, height: 80))
mainContainerView.backgroundColor = UIColor.white

var containerView = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
containerView.backgroundColor = UIColor.white
containerView.layer.cornerRadius = containerView.frame.width / 2

var innerView = UIView(frame: CGRect(x: 10, y: 10, width: 60, height: 60))
innerView.backgroundColor = UIColor.red
innerView.layer.cornerRadius = innerView.frame.width / 2

containerView.addSubview(innerView)

var containerView2 = UIView(frame: CGRect(x: 60, y: 0, width: 80, height: 80))
containerView2.backgroundColor = UIColor.yellow
containerView2.layer.cornerRadius = containerView2.frame.width / 2

var innerView2 = UIView(frame: CGRect(x: 10, y: 10, width: 60, height: 60))
innerView2.backgroundColor = UIColor.green
innerView2.layer.cornerRadius = innerView2.frame.width / 2

containerView2.addSubview(innerView2)

containerView.layer.zPosition = 2
containerView2.layer.zPosition = 1

mainContainerView.addSubview(containerView)
mainContainerView.addSubview(containerView2)

PlaygroundPage.current.liveView = mainContainerView

答案 4 :(得分:0)

简单建议:当您以编程方式设置边框颜色时,您可以根据背景颜色(如果背景颜色为实体(不是渐变))来更改它。

imageViewOne.layer.borderColor = imageViewOne.superview?.backgroundColor ?? UIColor.white
imageViewOne.layer.borderWidth = 2.0