├── .gitignore
├── EmojiLayout.plist
├── Makefile
├── PSEmojiLayout+KBResize.m
├── PSEmojiLayout+Layout.m
├── PSEmojiLayout.h
├── README.md
├── Tweak.xm
├── control
└── layout
└── Library
└── PreferenceLoader
└── Preferences
└── EmojiLayout
├── EmojiLayout.plist
├── EmojiLayout.png
├── EmojiLayout@2x.png
└── EmojiLayout@3x.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .theos
2 | packages
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/EmojiLayout.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Filter
6 |
7 | Bundles
8 |
9 | com.apple.UIKit
10 |
11 | CoreFoundationVersion
12 |
13 | 793
14 | 1144.17
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PACKAGE_VERSION = 1.2.0
2 |
3 | ifeq ($(SIMULATOR),1)
4 | TARGET = simulator:clang:latest:8.0
5 | ARCHS = x86_64 i386
6 | else
7 | TARGET = iphone:clang:latest:6.0
8 | ARCHS = armv7 arm64
9 | endif
10 |
11 | include $(THEOS)/makefiles/common.mk
12 |
13 | LIBRARY_NAME = EmojiLayout
14 | $(LIBRARY_NAME)_FILES = PSEmojiLayout+Layout.m PSEmojiLayout+KBResize.m Tweak.xm
15 | $(LIBRARY_NAME)_CFLAGS = -fobjc-arc
16 | $(LIBRARY_NAME)_INSTALL_PATH = /Library/MobileSubstrate/DynamicLibraries/EmojiPort
17 | $(LIBRARY_NAME)_EXTRA_FRAMEWORKS = CydiaSubstrate
18 | $(LIBRARY_NAME)_USE_SUBSTRATE = 1
19 |
20 | include $(THEOS_MAKE_PATH)/library.mk
21 | include ../../preferenceloader-sim/locatesim.mk
22 |
23 | ifeq ($(SIMULATOR),1)
24 | setup:: clean all
25 | @rm -f /opt/simject/$(LIBRARY_NAME).dylib
26 | @cp -v $(THEOS_OBJ_DIR)/$(LIBRARY_NAME).dylib /opt/simject
27 | @cp -v $(PWD)/$(LIBRARY_NAME).plist /opt/simject
28 | @sudo mkdir -p $(PL_SIMULATOR_PLISTS_PATH)
29 | @sudo cp -vR $(PWD)/EmojiLayout $(PL_SIMULATOR_PLISTS_PATH)/
30 | endif
31 |
--------------------------------------------------------------------------------
/PSEmojiLayout+KBResize.m:
--------------------------------------------------------------------------------
1 | #import "PSEmojiLayout.h"
2 | #import
3 | #import
4 |
5 | @implementation PSEmojiLayout (KBResize)
6 |
7 | + (CGFloat)getHeight:(NSString *)name chocoL:(CGFloat)chocoL chocoP:(CGFloat)chocoP truffleL:(CGFloat)truffleL truffleP:(CGFloat)truffleP l:(CGFloat)l p:(CGFloat)p padL:(CGFloat)padL padP:(CGFloat)padP {
8 | CGFloat height = 0.0;
9 | BOOL isLandscape = [name rangeOfString:@"Landscape"].location != NSNotFound
10 | || [name rangeOfString:@"Caymen"].location != NSNotFound
11 | || (!IS_IOS_OR_NEWER(iOS_7_0) && (
12 | [name rangeOfString:@"3587139855"].location != NSNotFound
13 | || [name rangeOfString:@"203519438"].location != NSNotFound));
14 | if ([name rangeOfString:@"Choco"].location != NSNotFound) {
15 | // iPhone 6
16 | height = isLandscape ? chocoL : chocoP;
17 | } else if ([name rangeOfString:@"Truffle"].location != NSNotFound) {
18 | // iPhone 6+
19 | height = isLandscape ? truffleL : truffleP;
20 | } else {
21 | // 3.5, 4-inches iDevices or iPad
22 | if (IS_IPAD)
23 | height = isLandscape ? padL : padP;
24 | else
25 | height = isLandscape ? l : p;
26 | }
27 | return height;
28 | }
29 |
30 | + (CGFloat)barHeight:(NSString *)name {
31 | return [self getHeight:name chocoL:37.0 chocoP:47.0 truffleL:40.0 truffleP:50.0 l:32.0 p:40.0 padL:56.0 padP:56.0];
32 | }
33 |
34 | + (CGFloat)keyboardHeight:(NSString *)name {
35 | return [self getHeight:name chocoL:194.0 chocoP:258.0 truffleL:194.0 truffleP:271.0 l:162.0 p:253.0 padL:398.0 padP:313.0];
36 | }
37 |
38 | + (CGFloat)scrollViewHeight:(NSString *)name {
39 | return [self keyboardHeight:name] - [self barHeight:name];
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/PSEmojiLayout+Layout.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "PSEmojiLayout.h"
3 | #import
4 | #import
5 | #import
6 | #import
7 | #import
8 | #import
9 |
10 | @implementation PSEmojiLayout
11 |
12 | + (BOOL)isPortrait {
13 | NSInteger orientation = [UIKeyboardImpl.activeInstance interfaceOrientation];
14 | return orientation == 1 || orientation == 2;
15 | }
16 |
17 | + (UIKeyboardEmojiScrollView *)emojiScrollView {
18 | return (UIKeyboardEmojiScrollView *)[NSClassFromString(@"UIKeyboardEmojiInputController") activeInputView];
19 | }
20 |
21 | + (NSInteger)rowCount:(BOOL)portrait {
22 | return [NSClassFromString(@"UIKeyboardEmojiGraphics") rowCount:portrait];
23 | }
24 |
25 | + (NSInteger)colCount:(BOOL)portrait {
26 | return [NSClassFromString(@"UIKeyboardEmojiGraphics") colCount:portrait];
27 | }
28 |
29 | + (CGSize)emojiSize:(BOOL)portrait {
30 | return [NSClassFromString(@"UIKeyboardEmojiGraphics") emojiSize:portrait];
31 | }
32 |
33 | + (CGPoint)margin:(BOOL)portrait {
34 | return CGPointMake(IS_IPAD ? (portrait ? MARGIN_IPAD_PORTRAIT : MARGIN_IPAD) : MARGIN, [self dotHeight]);
35 | }
36 |
37 | + (CGFloat)marginBottom:(BOOL)portrait {
38 | return IS_IPAD ? (portrait ? MARGIN_BOTTOM_IPAD_PORTRAIT : MARGIN_BOTTOM_IPAD) : MARGIN_BOTTOM;
39 | }
40 |
41 | + (CGFloat)offset:(BOOL)portrait {
42 | return IS_IOS_OR_NEWER(iOS_7_0) ? [NSClassFromString(@"UIKeyboardEmojiGraphics") emojiPageControlYOffset:portrait] : DEFAULT_OFFSET;
43 | }
44 |
45 | + (CGFloat)dotHeight {
46 | CGFloat height = 0.0;
47 | UIKeyboardEmojiScrollView *scrollView = [self emojiScrollView];
48 | if (scrollView) {
49 | _UIEmojiPageControl *pageControl = (_UIEmojiPageControl *)[scrollView valueForKey:@"_pageControl"];
50 | height = pageControl ? pageControl.frame.size.height : [pageControl _pageIndicatorImage].size.height;
51 | }
52 | return height == 0.0 ? DOT_HEIGHT : height;
53 | }
54 |
55 | + (CGFloat)_screenWidth {
56 | CGSize screenSize = UIScreen.mainScreen.bounds.size;
57 | return MIN(screenSize.width, screenSize.height);
58 | }
59 |
60 | + (CGFloat)_scrollViewHeight:(BOOL)portrait {
61 | NSString *type = portrait ? @"" : @"Landscape";
62 | if (!IS_IPAD) {
63 | CGFloat screenWidth = [self _screenWidth];
64 | if (screenWidth >= 414.0)
65 | type = [type stringByAppendingString:@"Truffle"];
66 | else if (screenWidth >= 375.0)
67 | type = [type stringByAppendingString:@"Choco"];
68 | }
69 | return [self scrollViewHeight:type];
70 | }
71 |
72 | + (CGFloat)keyboardWidth:(BOOL)portrait {
73 | if (IS_IOS_OR_NEWER(iOS_8_0))
74 | return [[NSClassFromString(@"UIPeripheralHost") sharedInstance] transformedContainerView].bounds.size.width;
75 | CGRect screenRect = UIScreen.mainScreen.bounds;
76 | return portrait ? screenRect.size.width : screenRect.size.height;
77 | }
78 |
79 | + (NSInteger)bestRowForLandscape {
80 | return IS_IPAD ? BEST_ROW_IPAD : BEST_ROW;
81 | }
82 |
83 | + (NSInteger)bestColForLandscape {
84 | if (IS_IPAD)
85 | return BEST_COL_IPAD;
86 | CGFloat w = [self keyboardWidth:NO];
87 | if (w >= 736.0)
88 | return BEST_COL_6S;
89 | if (w >= 568.0)
90 | return BEST_COL_NON4S;
91 | return BEST_COL;
92 | }
93 |
94 | + (CGFloat)paddingX:(BOOL)portrait {
95 | CGFloat w = [self keyboardWidth:portrait];
96 | NSInteger col = [self colCount:portrait];
97 | CGFloat padding = (w - (2 * [self margin:portrait].x) - (col * [self emojiSize:portrait].width)) / (col - 1);
98 | return padding;
99 | }
100 |
101 | + (CGFloat)paddingY:(BOOL)portrait {
102 | CGFloat h = [self _scrollViewHeight:portrait];
103 | NSInteger row = [self rowCount:portrait];
104 | CGFloat padding = (h - [self margin:portrait].y - [self offset:portrait] - [self marginBottom:portrait] - (row * [self emojiSize:portrait].height)) / (row - 1);
105 | return padding;
106 | }
107 |
108 | + (CGPoint)padding:(BOOL)portrait {
109 | return CGPointMake([self paddingX:portrait], [self paddingY:portrait]);
110 | }
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/PSEmojiLayout.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "../../PSPrefs/PSPrefs.x"
3 |
4 | #define DEFAULT_OFFSET 6.0
5 | #define MARGIN 8.5
6 | #define MARGIN_IPAD 10.0
7 | #define MARGIN_IPAD_PORTRAIT 12.0
8 | #define MARGIN_BOTTOM 6.0
9 | #define MARGIN_BOTTOM_IPAD 10.0
10 | #define MARGIN_BOTTOM_IPAD_PORTRAIT 14.0
11 | #define DOT_HEIGHT 14.0
12 |
13 | #define BEST_ROW_IPAD 5
14 | #define BEST_ROW 3
15 | #define BEST_COL_IPAD 16
16 | #define BEST_COL_6S 15
17 | #define BEST_COL_NON4S 14
18 | #define BEST_COL 12
19 |
20 | @interface PSEmojiLayout : NSObject
21 | @end
22 |
23 | @interface PSEmojiLayout (Layout)
24 | + (BOOL)isPortrait;
25 | + (UIKeyboardEmojiScrollView *)emojiScrollView;
26 | + (CGSize)emojiSize:(BOOL)portrait;
27 | + (CGPoint)margin:(BOOL)portrait;
28 | + (CGPoint)padding:(BOOL)portrait;
29 | + (CGFloat)paddingX:(BOOL)portrait;
30 | + (CGFloat)paddingY:(BOOL)portrait;
31 | + (CGFloat)offset:(BOOL)portrait;
32 | + (CGFloat)marginBottom:(BOOL)portrait;
33 | + (CGFloat)dotHeight;
34 | + (CGFloat)keyboardWidth:(BOOL)portrait;
35 | + (NSInteger)rowCount:(BOOL)portrait;
36 | + (NSInteger)colCount:(BOOL)portrait;
37 | + (NSInteger)bestRowForLandscape;
38 | + (NSInteger)bestColForLandscape;
39 | @end
40 |
41 | @interface PSEmojiLayout (KBResize)
42 | + (CGFloat)getHeight:(NSString *)name chocoL:(CGFloat)chocoL chocoP:(CGFloat)chocoP truffleL:(CGFloat)truffleL truffleP:(CGFloat)truffleP l:(CGFloat)l p:(CGFloat)p padL:(CGFloat)padL padP:(CGFloat)padP;
43 | + (CGFloat)barHeight:(NSString *)name;
44 | + (CGFloat)keyboardHeight:(NSString *)name;
45 | + (CGFloat)scrollViewHeight:(NSString *)name;
46 | @end
47 |
48 | #define SoftPSEmojiLayout NSClassFromString(@"PSEmojiLayout")
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | EmojiLayout
2 | =============
3 |
4 | Adjust rows and columns number of emoji page.
5 |
6 | Purpose
7 | ==========
8 |
9 | To mimic iOS 8.3+ emoji keyboard style.
10 |
--------------------------------------------------------------------------------
/Tweak.xm:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "../../PSPrefs/PSPrefs.x"
4 | #import "PSEmojiLayout.h"
5 | #import
6 | #import
7 | #import
8 | #import
9 | #import
10 | #import
11 |
12 | NSInteger row, col;
13 |
14 | %hook UIKeyboardEmojiGraphics
15 |
16 | + (NSInteger)rowCount:(BOOL)portrait {
17 | return portrait ? row : [PSEmojiLayout bestRowForLandscape];
18 | }
19 |
20 | + (NSInteger)colCount:(BOOL)portrait {
21 | return portrait ? col : [PSEmojiLayout bestColForLandscape];
22 | }
23 |
24 | + (CGPoint)padding:(BOOL)portrait {
25 | return [PSEmojiLayout padding:portrait];
26 | }
27 |
28 | + (CGPoint)margin:(BOOL)portrait {
29 | return [PSEmojiLayout margin:portrait];
30 | }
31 |
32 | %end
33 |
34 | BOOL pageZero = NO;
35 |
36 | %hook UIKeyboardEmojiPage
37 |
38 | - (void)setEmoji:(NSArray *)emoji {
39 | BOOL portrait = NO;
40 | if (!pageZero && emoji.count && ((portrait = [PSEmojiLayout isPortrait]) || IS_IPAD)) {
41 | NSInteger Row = [%c(UIKeyboardEmojiGraphics) rowCount:portrait];
42 | NSInteger Col = [%c(UIKeyboardEmojiGraphics) colCount:portrait];
43 | NSInteger Page = Row * Col;
44 | NSMutableArray *reorderedEmoji = [NSMutableArray arrayWithCapacity:Page];
45 | UIKeyboardEmoji *emptyEmoji = [SoftPSEmojiUtilities emojiWithString:@""];
46 | for (NSInteger i = 0; i < Page; ++i) {
47 | NSInteger emojiIndex = ((i % Col) * Row) + (i / Col);
48 | [reorderedEmoji addObject:emojiIndex < emoji.count ? [emoji objectAtIndex:emojiIndex] : emptyEmoji];
49 | }
50 | if (reorderedEmoji.count) {
51 | %orig(reorderedEmoji);
52 | return;
53 | }
54 | }
55 | %orig;
56 | }
57 |
58 | - (UIKeyboardEmojiView *)closestForPoint:(CGPoint)point {
59 | UIKeyboardEmojiView *orig = %orig;
60 | return orig.emoji.emojiString.length == 0 ? nil : orig;
61 | }
62 |
63 | %end
64 |
65 | %hook UIKeyboardEmojiScrollView
66 |
67 | - (void)layoutRecents {
68 | pageZero = YES;
69 | %orig;
70 | pageZero = NO;
71 | }
72 |
73 | - (void)layoutPages {
74 | if (MSHookIvar(self, "_currentPage") >= MSHookIvar(self, "_pages").count)
75 | MSHookIvar(self, "_currentPage") = 0;
76 | %orig;
77 | }
78 |
79 | %end
80 |
81 | %group iOS6Up
82 |
83 | %hook UIKeyboardEmojiInputController
84 |
85 | - (void)emojiUsed:(UIKeyboardEmoji *)emoji {
86 | NSString *emojiString = emoji.emojiString;
87 | if (!emojiString || [emojiString isEqualToString:@""])
88 | return;
89 | if ([emoji respondsToSelector:@selector(hasDingbat)] && [emoji hasDingbat])
90 | emojiString = [NSString stringWithFormat:@"%@%@", emojiString, FE0F];
91 | __block __weak UIKeyboardImpl *kbImpl = [UIKeyboardImpl sharedInstance];
92 | if ([kbImpl acceptInputString:emojiString]) {
93 | if (IS_IOS_OR_NEWER(iOS_7_0)) {
94 | [kbImpl.taskQueue addTask:^{
95 | [kbImpl addInputString:emojiString withFlags:0 executionContext:kbImpl.taskQueue.executionContext];
96 | }];
97 | } else
98 | [kbImpl addInputString:emojiString fromVariantKey:0];
99 | }
100 | #define usageHistory MSHookIvar(self, "_usageHistory")
101 | UIKeyboardEmojiDefaultsController *emojiDefaultsController = [%c(UIKeyboardEmojiDefaultsController) sharedController];
102 | if (usageHistory == nil) {
103 | id usageHistoryKey = emojiDefaultsController.usageHistoryKey;
104 | if (usageHistoryKey)
105 | usageHistory = (__bridge NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFPropertyListRef)usageHistoryKey, kCFPropertyListMutableContainersAndLeaves);
106 | else
107 | usageHistory = [[NSMutableDictionary alloc] initWithCapacity:10];
108 | }
109 | #define recents MSHookIvar(self, "_recents")
110 | if (recents == nil) {
111 | id recentsKey = emojiDefaultsController.recentsKey;
112 | if (recentsKey)
113 | recents = (__bridge NSMutableArray *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFPropertyListRef)recentsKey, kCFPropertyListMutableContainersAndLeaves);
114 | else
115 | recents = [[NSMutableArray alloc] initWithCapacity:10];
116 | }
117 | #define currentSequence MSHookIvar(self, "_currentSequence")
118 | emojiDefaultsController.currentSequenceKey = currentSequence;
119 | NSNumber *sequence_num = [NSNumber numberWithInt:currentSequence++];
120 | NSString *emojiString2 = emoji.emojiString;
121 | NSMutableArray *emojiInHistory = usageHistory[emojiString2];
122 | if (emojiInHistory == nil)
123 | emojiInHistory = [NSMutableArray arrayWithCapacity:0];
124 | [emojiInHistory addObject:sequence_num];
125 | [usageHistory setObject:emojiInHistory forKey:emojiString2];
126 | emojiDefaultsController.usageHistoryKey = usageHistory;
127 | double scoreForEmoji = [self scoreForEmoji:emoji];
128 | NSUInteger recentsCount = recents.count;
129 | NSUInteger maxCount = [%c(UIKeyboardEmojiGraphics) rowCount:YES] * [%c(UIKeyboardEmojiGraphics) colCount:YES];
130 | NSUInteger indexOfEmojiToBeRemoved = [recents indexOfObject:emoji];
131 | if (recentsCount && indexOfEmojiToBeRemoved != NSNotFound)
132 | [recents removeObjectAtIndex:indexOfEmojiToBeRemoved];
133 | else if (recentsCount > maxCount) {
134 | UIKeyboardEmoji *lastRecentEmoji = [recents lastObject];
135 | double scoreOfLastRecentEmoji = [self scoreForEmoji:lastRecentEmoji];
136 | if (scoreForEmoji > scoreOfLastRecentEmoji)
137 | [recents removeLastObject];
138 | }
139 | NSUInteger idx = 0;
140 | if (recentsCount) {
141 | do {
142 | UIKeyboardEmoji *emojiAtIndex = recents[idx];
143 | double scoreOfEmojiAtIndex = [self scoreForEmoji:emojiAtIndex];
144 | if (scoreForEmoji > scoreOfEmojiAtIndex)
145 | break;
146 | } while (++idx != recentsCount);
147 | }
148 | [recents insertObject:emoji atIndex:idx];
149 | emojiDefaultsController.recentsKey = recents;
150 | ((UIKeyboardEmojiCategory *)[%c(UIKeyboardEmojiCategory) categoryForType:0]).emoji = recents;
151 | }
152 |
153 | %end
154 |
155 | %end
156 |
157 | %group iOS7Up
158 |
159 | %hook _UIEmojiPageControl
160 |
161 | - (void)layoutSubviews {
162 | self.hidesForSinglePage = NO;
163 | %orig;
164 | }
165 |
166 | %end
167 |
168 | %hook UIKeyboardEmojiCategory
169 |
170 | + (NSUInteger)hasVariantsForEmoji:(NSString *)emoji {
171 | if (!emoji || [emoji isEqualToString:@""])
172 | return NO;
173 | return %orig;
174 | }
175 |
176 | %end
177 |
178 | %end
179 |
180 | #if !__LP64__
181 |
182 | %group iOS56
183 |
184 | %hook EmojiPageControl
185 |
186 | - (void)layoutSubviews {
187 | self.hidesForSinglePage = NO;
188 | %orig;
189 | }
190 |
191 | %end
192 |
193 | BOOL draw = NO;
194 |
195 | %hook UIKeyboardEmojiPage
196 |
197 | - (void)drawRect:(CGRect)rect {
198 | draw = YES;
199 | %orig;
200 | draw = NO;
201 | }
202 |
203 | %end
204 |
205 | %end
206 |
207 | %group iOS6
208 |
209 | %hookf(void, CTFontDrawGlyphs, CTFontRef font, const CGGlyph glyphs[], const CGPoint positions[], size_t count, CGContextRef context) {
210 | if (draw && glyphs[0] == 0)
211 | return;
212 | %orig;
213 | }
214 |
215 | %end
216 |
217 | #endif
218 |
219 | static const NSString *tweakIdentifier = @"com.PS.EmojiLayout";
220 | static const NSString *colKey = @"columns";
221 | static const NSString *rowKey = @"rows";
222 |
223 | HaveCallback() {
224 | GetPrefs();
225 | GetInt2(col, IS_IPAD ? 12 : 8);
226 | GetInt2(row, IS_IPAD ? 3 : 5);
227 | }
228 |
229 | %ctor {
230 | HaveObserver();
231 | callback();
232 | dlopen(realPath2(@"/usr/lib/libEmojiLibrary.dylib"), RTLD_NOW);
233 | if (IS_IOS_OR_NEWER(iOS_6_0)) {
234 | %init(iOS6Up);
235 | }
236 | if (IS_IOS_OR_NEWER(iOS_7_0)) {
237 | %init(iOS7Up);
238 | }
239 | #if !__LP64__
240 | else {
241 | %init(iOS56);
242 | if (IS_IOS_BETWEEN(iOS_6_0, iOS_6_1)) {
243 | %init(iOS6);
244 | }
245 | }
246 | #endif
247 | %init;
248 | }
249 |
--------------------------------------------------------------------------------
/control:
--------------------------------------------------------------------------------
1 | Package: com.ps.emojilayout
2 | Name: EmojiLayout
3 | Depends: preferenceloader, firmware (>= 6.0), firmware (<< 8.3)
4 | Version: 1.0.0
5 | Architecture: iphoneos-arm
6 | Description: Layout the emoji keyboard.
7 | Maintainer: PoomSmart
8 | Author: PoomSmart
9 | Section: Tweaks
10 | Depiction: https://poomsmart.github.io/repo/depictions/emojilayout.html
11 | Tag: compatible::ios6, compatible::ios7, compatible::ios8
12 |
--------------------------------------------------------------------------------
/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | title
6 | EmojiLayout
7 | entry
8 |
9 | cell
10 | PSLinkCell
11 | icon
12 | EmojiLayout.png
13 | label
14 | EmojiLayout
15 |
16 | items
17 |
18 |
19 | cell
20 | PSGroupCell
21 | label
22 | Layout
23 | footerAlignment
24 | 1
25 | footerText
26 | iPhone (3.5/4-inches) default: (row: 5, col: 8)
27 | iPhone 6 Plus default: (row: 5, col: 9)
28 | iPad default: (row: 3, col: 12)
29 |
30 | © 2017 - 2024 PoomSmart
31 |
32 |
33 | cell
34 | PSEditTextCell
35 | detail
36 | PSDetailController
37 | default
38 |
39 | defaults
40 | com.PS.EmojiLayout
41 | PostNotification
42 | com.PS.EmojiLayout/ReloadPrefs
43 | key
44 | rows
45 | placeholder
46 | emoji per row
47 | isNumeric
48 |
49 |
50 |
51 | cell
52 | PSEditTextCell
53 | detail
54 | PSDetailController
55 | default
56 |
57 | defaults
58 | com.PS.EmojiLayout
59 | PostNotification
60 | com.PS.EmojiLayout/ReloadPrefs
61 | key
62 | columns
63 | placeholder
64 | emoji per column
65 | isNumeric
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PoomSmart/EmojiLayout/bb641d6da9a94edd7c0f9239496a02167062a249/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout.png
--------------------------------------------------------------------------------
/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PoomSmart/EmojiLayout/bb641d6da9a94edd7c0f9239496a02167062a249/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout@2x.png
--------------------------------------------------------------------------------
/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PoomSmart/EmojiLayout/bb641d6da9a94edd7c0f9239496a02167062a249/layout/Library/PreferenceLoader/Preferences/EmojiLayout/EmojiLayout@3x.png
--------------------------------------------------------------------------------