An expressive emoji rating view for iOS.
TTGEmojiRate turns feedback into a living expression. Its original interaction is vertical drag: users move the emoji up or down to score a moment, express mood, and make ratings feel closer to a real emotional response.
- ๐ Emotion-first rating UI for reviews, surveys, NPS-style prompts, satisfaction scores, and lightweight mood input.
- ๐ Free-step values by default, with optional half-step or whole-step snapping when a product needs stricter scoring.
- ๐จ Multiple face shapes, morphing outlines, filled faces, dynamic colors, and gradient strokes/fills.
- โ๏ธ Custom path replacement or overlay for branded symbols, waveform reactions, badges, or delegate-driven drawings.
- ๐ Read-only display, tap-to-rate, animated value updates, callbacks, and Interface Builder-friendly properties.
- ๐งช Rebuilt Swift and Objective-C example apps with focused demos and an interactive playground.
Create the control, choose a range, and listen for score changes:
Shape the rating surface with face outlines, fills, and gradients:
Replace or overlay the built-in drawing when the rating UI should feel product-specific:
import TTGEmojiRate
let rateView = EmojiRateView(frame: CGRect(x: 0, y: 0, width: 220, height: 220))
rateView.minimumRateValue = 0
rateView.maximumRateValue = 10
rateView.rateStep = 0
rateView.rateValueChangeCallback = { score in
print("Score:", score)
}
view.addSubview(rateView)Add TTGEmojiRate to your Podfile:
pod "TTGEmojiRate"Add TTGEmojiRate to your Cartfile:
github "zekunyan/TTGEmojiRate"
rateStep = 0 keeps motion continuous. Use 0.5 or 1 when you need snapped survey values.
rateView.minimumRateValue = 1
rateView.maximumRateValue = 5
rateView.rateStep = 0.5
rateView.setRateValue(4.5, animated: true)rateView.faceShape = TTGEmojiRateFaceShape.blob.rawValue
rateView.faceShapeMorphEnabled = true
rateView.faceFillEnabled = true
rateView.faceFillGradientEnabled = true
rateView.rateGradientColorEnabled = true
rateView.rateGradientColors = [
.systemCyan,
.systemBlue,
.systemPurple
]rateView.setEmojiExpressionPreset(.playful)
rateView.setEmojiEyeStyle(.heart)
rateView.setEmojiMouthStyle(.openSmile)rateView.customEmojiPathMode = TTGEmojiRateCustomPathMode.replace.rawValue
rateView.customEmojiPathProvider = { rect, progress, view in
let path = UIBezierPath()
let faceRect = rect.insetBy(dx: 12, dy: 12)
path.append(UIBezierPath(ovalIn: faceRect))
let symbol = UIBezierPath()
let midY = rect.midY + (1 - progress) * 20
symbol.move(to: CGPoint(x: rect.minX + 54, y: midY))
symbol.addLine(to: CGPoint(x: rect.midX, y: midY - 18))
symbol.addLine(to: CGPoint(x: rect.maxX - 54, y: midY))
path.append(symbol)
return path
}Use .overlay when you want to keep the built-in emoji and draw extra artwork on top.
rateView.isReadOnly = true
rateView.isTapToRateEnabled = false
rateView.setRateColor(from: .systemBlue, to: .systemGreen)The repository includes both Swift and Objective-C examples. Each example is fully code-driven and includes:
- A playground for live configuration.
- Focused demos for gesture input, face shapes, gradients, custom paths, read-only state, and programmatic updates.
- Slider-backed screens for precise testing alongside direct emoji interaction.
Run pod install inside Example-Swift or Example-Objc, then open the generated workspace.
- iOS 16.0+
- Xcode 15+
- Swift 5.9+
Inspired by Rating Version A - Hoang Nguyen.
Android version: PeterSmileRate by SilicorniO.
Blog: ๅๅๅฅ็ๆๆฏBlog - Swiftๅผๆบ้กน็ฎ: TTGEmojiRate็ๅฎ็ฐ
zekunyan, zekunyan@163.com
TTGEmojiRate is available under the MIT license. See the LICENSE file for more info.



