{"id":2684,"url":"https://github.com/kevin-lyn/STPopup","last_synced_at":"2025-08-03T00:32:19.978Z","repository":{"id":37720692,"uuid":"42387347","full_name":"kevin-lyn/STPopup","owner":"kevin-lyn","description":"STPopup provides STPopupController, which works just like UINavigationController in popup style, for both iPhone and iPad. It's written in Objective-C and compatible with Swift.","archived":false,"fork":false,"pushed_at":"2021-12-11T21:09:16.000Z","size":310,"stargazers_count":2599,"open_issues_count":37,"forks_count":345,"subscribers_count":57,"default_branch":"master","last_synced_at":"2024-10-29T17:42:53.293Z","etag":null,"topics":["bottom-sheet","bulletin-board","form-sheet","ios","ipad","iphone","popup","ui","ui-components"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevin-lyn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-13T07:21:56.000Z","updated_at":"2024-10-27T10:13:14.000Z","dependencies_parsed_at":"2022-08-08T21:30:25.531Z","dependency_job_id":null,"html_url":"https://github.com/kevin-lyn/STPopup","commit_stats":null,"previous_names":["kevin0571/stpopup"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin-lyn%2FSTPopup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin-lyn%2FSTPopup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin-lyn%2FSTPopup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevin-lyn%2FSTPopup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevin-lyn","download_url":"https://codeload.github.com/kevin-lyn/STPopup/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228510773,"owners_count":17931761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bottom-sheet","bulletin-board","form-sheet","ios","ipad","iphone","popup","ui","ui-components"],"created_at":"2024-01-05T20:16:20.108Z","updated_at":"2024-12-06T18:30:41.196Z","avatar_url":"https://github.com/kevin-lyn.png","language":"Objective-C","funding_links":[],"categories":["UI","Objective-C"],"sub_categories":["Popup"],"readme":"# STPopup ![CI Status](https://img.shields.io/travis/kevin0571/STPopup.svg?style=flat) ![Version](http://img.shields.io/cocoapods/v/STPopup.svg?style=flag) ![License](https://img.shields.io/cocoapods/l/STPopup.svg?style=flag)\n`STPopup` provides `STPopupController`, which works just like `UINavigationController` in popup style, for both iPhone and iPad. It's written in Objective-C and compatible with Swift.\n\n**Features:**\n- Push/Pop view controller into/out of `STPopupController` just like `UINavigationController`.\n- Set navigation items through `self.navigationItem` just like using a `UINavigationController`.\n- Support both \"Form Sheet\" and \"Bottom Sheet\" style.\n- Work well with storyboard(including segue).\n- Customize UI by using `UIAppearance`.\n- Customizable popup transition style.\n- Auto-reposition of popup view when keyboard shows up, make sure your `UITextField`/`UITextView` won't be covered by the keyboard.\n- Drag navigation bar to dismiss popup view.\n- Support both portrait and landscape orientation in iPhone and iPad.\n- iOS 7+.\n- Compatible with Swift.\n\n## Use Cases\n![Use Cases](https://user-images.githubusercontent.com/1491282/57985696-b6e01300-7a63-11e9-91a9-b5aa55262967.jpg)\n\n## Get Started\n**CocoaPods**\n```ruby\npod 'STPopup'\n```\n**Carthage**\n```ruby\ngithub \"kevin0571/STPopup\"\n```\n  \n**Import header file**  \nObjective-C\n```objc\n#import \u003cSTPopup/STPopup.h\u003e\n```\nSwift\n```swift\nimport STPopup\n```\n\n**Initialize and present STPopupController**  \nObjective-C\n```objc\nSTPopupController *popupController = [[STPopupController alloc] initWithRootViewController:viewController];\n[popupController presentInViewController:self];\n```\nSwift\n```swift\nlet popupController = STPopupController(rootViewController: viewController)\npopupController.present(in: self)\n```\n\n**Set content size in view controller**  \nObjective-C\n```objc\n@implementation ViewController\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        self.title = @\"View Controller\";\n        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@\"Next\" style:UIBarButtonItemStylePlain target:self action:@selector(nextBtnDidTap)];\n        // It's required to set content size of popup.\n        self.contentSizeInPopup = CGSizeMake(300, 400);\n        self.landscapeContentSizeInPopup = CGSizeMake(400, 200);\n    }\n    return self;\n}\n\n@end\n```\nSwift\n```swift\nclass ViewController: UIViewController {\n    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {\n        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)\n        title = \"View Controller\"\n        navigationItem.rightBarButtonItem = UIBarButtonItem(title: \"Next\", style: .plain, target: self, action: #selector(nextBtnDidTap))\n        // It's required to set content size of popup.\n        contentSizeInPopup = CGSize(width: 300, height: 400)\n        landscapeContentSizeInPopup = CGSize(width: 400, height: 200)\n    }\n}\n```\n**Set content size of view controller which is loaded from Storyboard**  \nSet content size in storyboard or in `awakeFromNib`.  \n![Storyboard](https://user-images.githubusercontent.com/1491282/57982394-dca5f180-7a3c-11e9-8d63-3ca6c3837860.png)\n\n**Push, pop and dismiss view controllers**  \nObjective-C\n```objc\n[self.popupController pushViewController:[ViewController new] animated:YES];\n[self.popupController popViewControllerAnimated:YES]; // Popup will be dismissed if there is only one view controller in the popup view controller stack\n[self.popupController dismiss];\n```\nSwift\n```swift\npopupController?.push(viewController, animated: true)\npopupController?.popViewController(animated: true) // Popup will be dismissed if there is only one view controller in the popup view controller stack\npopupController?.dismiss()\n```\n\n![Push \u0026 Pop](https://cloud.githubusercontent.com/assets/1491282/9857915/0d4ab3ee-5b50-11e5-81bc-8fbae3ad8c06.gif)\n\n**Bottom sheet style**  \nObjective-C\n```objc\nSTPopupController *popupController = [[STPopupController alloc] initWithRootViewController:[ViewController new]];\npopupController.style = STPopupStyleBottomSheet;\n[popupController presentInViewController:self];\n```\nSwift\n```swift\nlet popupController = STPopupController(rootViewController: viewController)\npopupController.style = .bottomSheet\npopupController.present(in: self)\n```\n![Bottom Sheet](https://cloud.githubusercontent.com/assets/1491282/10417963/7649f356-7080-11e5-8f3c-0cb817b8353e.gif)\n\n**Customize popup transition style**  \nObjective-C\n```objc\n#pragma mark - STPopupControllerTransitioning\n\n- (NSTimeInterval)popupControllerTransitionDuration:(STPopupControllerTransitioningContext *)context\n{\n    return context.action == STPopupControllerTransitioningActionPresent ? 0.5 : 0.35;\n}\n\n- (void)popupControllerAnimateTransition:(STPopupControllerTransitioningContext *)context completion:(void (^)())completion\n{\n    // Popup will be presented with an animation sliding from right to left.\n    UIView *containerView = context.containerView;\n    if (context.action == STPopupControllerTransitioningActionPresent) {\n        containerView.transform = CGAffineTransformMakeTranslation(containerView.superview.bounds.size.width - containerView.frame.origin.x, 0);\n        \n        [UIView animateWithDuration:[self popupControllerTransitionDuration:context] delay:0 usingSpringWithDamping:1 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{\n            context.containerView.transform = CGAffineTransformIdentity;\n        } completion:^(BOOL finished) {\n            completion();\n        }];\n    }\n    else {\n        [UIView animateWithDuration:[self popupControllerTransitionDuration:context] delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n            containerView.transform = CGAffineTransformMakeTranslation(- 2 * (containerView.superview.bounds.size.width - containerView.frame.origin.x), 0);\n        } completion:^(BOOL finished) {\n            containerView.transform = CGAffineTransformIdentity;\n            completion();\n        }];\n    }\n}\n\n// Use custom transitioning in popup controller\nSTPopupController *popupController = [[STPopupController alloc] initWithRootViewController:viewController];\npopupController.transitionStyle = STPopupTransitionStyleCustom;\npopupController.transitioning = self;\n[popupController presentInViewController:self];\n```\nSwift\n```swift\n// MARK: STPopupControllerTransitioning\n\nfunc popupControllerTransitionDuration(_ context: STPopupControllerTransitioningContext) -\u003e TimeInterval {\n    return context.action == .present ? 0.5 : 0.35\n}\n\nfunc popupControllerAnimateTransition(_ context: STPopupControllerTransitioningContext, completion: @escaping () -\u003e Void) {\n    // Popup will be presented with an animation sliding from right to left.\n    let containerView = context.containerView\n    if context.action == .present {\n        containerView.transform = CGAffineTransform(translationX: containerView.superview!.bounds.size.width - containerView.frame.origin.x, y: 0)\n        UIView.animate(withDuration: popupControllerTransitionDuration(context), delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {\n            containerView.transform = .identity\n        }, completion: { _ in\n            completion()\n        });\n    } else {\n        UIView.animate(withDuration: popupControllerTransitionDuration(context), delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {\n            containerView.transform = CGAffineTransform(translationX: -2 * (containerView.superview!.bounds.size.width - containerView.frame.origin.x), y: 0)\n        }, completion: { _ in\n            containerView.transform = .identity\n            completion()\n        });\n    }\n}\n\n// Use custom transitioning in popup controller\nlet popupController = let popupController = STPopupController(rootViewController: viewController)\npopupController.transitionStyle = .custom\npopupController.transitioning = self\npopupController.present(in: self)\n```\n\n**Blur background**  \nObjective-C\n```objc\nSTPopupController *popupController = [[STPopupController alloc] initWithRootViewController:[PopupViewController1 new]];\nif (NSClassFromString(@\"UIBlurEffect\")) {\n    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];\n    popupController.backgroundView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];\n}\n```\nSwift\n```swift\nlet popupController = let popupController = STPopupController(rootViewController: viewController)\nif NSClassFromString(\"UIBlurEffect\") != nil {\n    let blurEffect = UIBlurEffect(style: .dark)\n    popupController.backgroundView = UIVisualEffectView(effect: blurEffect)\n}\n```\n\n**Action of tapping on area outside of popup**  \nObjective-C\n```objc\n[popupController.backgroundView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundViewDidTap)]];\n```\nSwift\n```swift\npopupController.backgroundView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(backgroundViewDidTap)))\n```\n\n**Customize UI**  \nObjective-C\n```objc\n[STPopupNavigationBar appearance].barTintColor = [UIColor colorWithRed:0.20 green:0.60 blue:0.86 alpha:1.0];\n[STPopupNavigationBar appearance].tintColor = [UIColor whiteColor];\n[STPopupNavigationBar appearance].barStyle = UIBarStyleDefault;\n[STPopupNavigationBar appearance].titleTextAttributes = @{ NSFontAttributeName: [UIFont fontWithName:@\"Cochin\" size:18], NSForegroundColorAttributeName: [UIColor whiteColor] };\n    \n[[UIBarButtonItem appearanceWhenContainedIn:[STPopupNavigationBar class], nil] setTitleTextAttributes:@{ NSFontAttributeName:[UIFont fontWithName:@\"Cochin\" size:17] } forState:UIControlStateNormal];\n```\nSwift\n```swift\nSTPopupNavigationBar.appearance().barTintColor = UIColor(red: 0.2, green: 0.6, blue: 0.86, alpha: 1)\nSTPopupNavigationBar.appearance().tintColor = .white\nSTPopupNavigationBar.appearance().barStyle = .default\nSTPopupNavigationBar.appearance().titleTextAttributes = [\n    .font: UIFont(name: \"Cochin\", size: 18) ?? .systemFont(ofSize: 18),\n    .foregroundColor: UIColor.white,\n]\nUIBarButtonItem\n    .appearance(whenContainedInInstancesOf: [STPopupNavigationBar.self])\n    .setTitleTextAttributes([\n        .font: UIFont(name: \"Cochin\", size: 18) ?? .systemFont(ofSize: 18),\n        ], for: .normal)\n```\n![Customize UI](https://cloud.githubusercontent.com/assets/1491282/9911306/0f6db056-5cd4-11e5-9329-33b0cf02e1b0.png)\n\n**Auto-reposition when keyboard is showing up**  \nThis is default behavior.  \n![Auto-reposition](https://cloud.githubusercontent.com/assets/1491282/9858277/5b29b130-5b52-11e5-9569-7560a0853493.gif)\n\n**Drag to dismiss**  \nThis is default behavior.  \n![Drag to dismiss](https://cloud.githubusercontent.com/assets/1491282/9858334/b103fc96-5b52-11e5-9c3f-517367ed9386.gif)\n\n**Handle orientation change**  \nThis is default behavior.  \n![Orientation change](https://cloud.githubusercontent.com/assets/1491282/9858372/e6538880-5b52-11e5-8882-8705588606ba.gif)\n\nPlease checkout the example project for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevin-lyn%2FSTPopup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevin-lyn%2FSTPopup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevin-lyn%2FSTPopup/lists"}