我有一个视图控制器A,显示状态栏在顶部.从该视图控制器我想呈现B隐藏状态栏的另一个视图控制器.为了实现这一点,我重写了属性
override var prefersStatusBarHidden: Bool {
return true
}
Run Code Online (Sandbox Code Playgroud)
在B.为了在状态栏(dis)出现时强制执行平滑动画,我也会覆盖该属性
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
Run Code Online (Sandbox Code Playgroud)
然而,当我现在呈现视图控制器B从A状态栏突然消失,同时A仍然可见,就在动画模式转换开始之前.
我正在寻找一种方法来解决这个"跳跃状态栏"的行为.理想情况下,我希望有一个干净的分离:
A:显示状态栏B:不显示状态栏这样,当我出现时B,状态栏就会被它覆盖.
由于状态栏似乎是一个不属于任何特定视图控制器的全局视图,因此可能很难实现这种行为.因此,如果不能复制这种精确的动画行为,我也很高兴如果状态栏在视图控制器转换期间平滑滑出.我怎样才能做到这一点?
我已MKUserTrackingButton在地图视图中将 Apple 的新功能添加到我的应用程序中。当用户先前已授予使用位置服务的许可(例如CLAuthorizationStatus.authorizedWhenInUse)时,它可以正常工作。
但是,当用户拒绝权限或权限状态未确定时,用户跟踪按钮会变成活动指示器(又名微调器)并且永不停止旋转。
相反,我想像在 Apple Maps 应用程序中一样显示 iOS 权限警报,或者至少显示某种警报,以向用户提示为什么它不起作用。当然,我也希望活动指示器停止并返回默认的“指南针”图标。
不幸的是,MKUserTrackingButton它不是一个 sublass,UIButton所以我不能向它添加任何目标,而且似乎没有 API 来改变按钮的视觉状态。
知道如何做到这一点吗?
我正在寻找一种通用方法来获取 Swift 中嵌套类型的全名,即当我如下定义嵌套结构时:
struct A {
struct B {
struct C {
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个 的实例C,然后我想要一个方法来返回该实例类型的完整路径:
let c = A.B.C()
fullTypeName(c) // should return "A.B.C"
Run Code Online (Sandbox Code Playgroud)
当我使用
String(describing: type(of: c))
Run Code Online (Sandbox Code Playgroud)
它只返回最后一个组件C,即相对于定义它的范围的类型名称。
当我使用
String(reflecting: type(of: c))
Run Code Online (Sandbox Code Playgroud)
它实际上返回整个路径,但带有一些丑陋的前缀__lldb_expr_22.A.B.C。
我String从这里创建了一个简单的自定义初始化程序:
extension String {
init<Subject>(describingNestedType: Subject) {
let string = String(reflecting: Subject.self)
let components = string.split(separator: ".")
let path = components.dropFirst().joined(separator: ".")
self = path
}
}
Run Code Online (Sandbox Code Playgroud)
效果很好:
let c = A.B.C()
let cString …Run Code Online (Sandbox Code Playgroud) 对于我的iPhone应用程序,我想实现通过使用CocoaSoundCloudAPI将文件上传到Soundcloud的选项.在" 如何直接使用SoundCloud API "说明中,解释了如何以模态方式呈现loginViewController:
- (void)login {
[SCSoundCloud requestAccessWithPreparedAuthorizationURLHandler:
^(NSURL *preparedURL){
SCLoginViewController *loginViewController;
loginViewController =
[SCLoginViewController loginViewControllerWithPreparedURL:preparedURL
completionHandler:^(NSError *error){
if (SC_CANCELED(error)) {
NSLog(@"Canceled!");
} else if (error) {
NSLog(@"Ooops, something went wrong: %@", [error localizedDescription]);
} else {
NSLog(@"Done!");
}
}];
[self presentModalViewController:loginViewController
animated:YES];
}];
}
Run Code Online (Sandbox Code Playgroud)
现在我换了
[self presentModalViewController:loginViewController
animated:YES];
Run Code Online (Sandbox Code Playgroud)
同
[self presentViewController:loginViewController
animated:YES
completion:nil];
Run Code Online (Sandbox Code Playgroud)
因为第一种方法在iOS 7中已弃用.
但问题是,loginViewController当以这种方式呈现时,Soundcloud会重叠状态栏.由于我不想更改Soundcloud API,因此我没有选择loginViewController相应的- viewDidLoad方法,例如在其方法中(如Stackoverflow上的许多其他帖子所示).

不幸的是,有一个工具栏,顶部有一个按钮loginViewController.如何loginViewController从我自己的(呈现)视图控制器内部配置我,使其在呈现时不会与状态栏重叠?
我有UITabBarController四个标签。在选择选项卡时显示的每个视图控制器中,我都有一个重置按钮。点击按钮将改变所有视图控制器的外观。特别是,它会改变不同视图控制器中某些标签的文本。
是否有一些推荐的方法可以同时更新 a 的所有视图控制器,UITabBarController即让它们重新加载视图?
我目前的方法是使这些视图控制器符合协议
@protocol XYReloadableViewController
- (void)reloadContents;
@end
Run Code Online (Sandbox Code Playgroud)
然后-reloadContents在点击按钮时将消息发送到所有视图控制器:
- (IBAction)touchUpInsideResetButton {
// ...
NSArray *viewControllers = self.tabBarController.viewControllers;
for (UIViewController<XYReloadableViewController> *viewController in viewControllers) {
[viewController reloadContents];
}
}
Run Code Online (Sandbox Code Playgroud)
然后在每个视图控制器中,我必须实现该方法:
- (void)reloadContents {
[self.tableView reloadData];
// other updates to UI ...
}
Run Code Online (Sandbox Code Playgroud)
但这似乎有点太复杂了。那么有没有更简单的方法来告诉视图控制器重新加载他们的视图?
编辑:如果我UINavigationController在某些选项卡或容器视图控制器中显示 a 会发生什么?我需要沿着所有子视图控制器的链传递消息......
有没有办法为用 录制的 AAC 文件设置元数据,如artist、等?titlegenreAVAudioRecorder
对于 MP3 文件,有ID3 标签。但是,我还没有找到 AAC 文件的等效项。我已经搜索过 Apple Developer Docs,但没有成功,但必须有某种方法来设置这些属性,因为当在VLC或foobar2000等音频播放器中播放从 iTunes 下载的 AAC 文件时,它确实可以识别元数据,甚至专辑封面。
我在为UISegmentedControl. 我相信只有在设置过大的图像(超出片段的边界)时才会发生这种情况,我知道正确的解决方案是首先使用合适的图像。但是,我观察到了我想了解的那些大图像的奇怪调整大小行为:
这是两个相同的截图UISegmentedControl。唯一的区别是我为它们的片段使用了不同的图像。
我对控制组件进行了颜色编码,如下所示:
黄色:段分隔符
黑色:段背景
正如你所看到的,一些片段图像总是水平扭曲。在第一个带有快乐笑脸的示例中,内部两个图像以正确的纵横比出现,而外部图像被压缩。在带有痛苦笑脸的第二个示例中,外部图像以正确的纵横比显示,而内部两个图像被拉伸。
显然 iOS 处理内部和外部段图像的方式不同。有谁知道为什么会这样?iOS 在什么情况下会挤压或拉伸分段图像?
我已在我的应用程序中启用了通用链接。处理这些链接的相应委托调用是
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
if canHandle(userAcitivity) {
// Handle the universal link.
}
else {
// ?? Don't handle the universal link.
return false
}
}
Run Code Online (Sandbox Code Playgroud)
不,我想知道false从该方法返回时到底会发生什么。一开始我以为Safari会像没有启用通用链接那样简单地打开链接。但是,我发现我的应用程序仍处于打开状态,并且文档指出:
如果您未实现此方法,或者您的实现返回
false,则iOS会尝试为您的应用创建一个使用URL打开的文档。
创建什么样的文档,我的应用程序如何收到通知?
我的最终目标是让用户能够将文本拆分为一个NSTextView或UITextView多个部分,其中两个后续部分通过自定义视图分隔符在视觉上分开(可能,但不一定是水平规则 - 我希望能够调整分离器的视觉外观没有麻烦)。
我需要一个适用于两个平台的解决方案:macOS 和 iOS。
(我的相关问题集中在 macOS 的解决方案上,并且有一个使用NSTextAttachmentCells 在 iOS 上不可用。)
我目前解决这个问题的方法如下:
当用户点击该按钮时,我会创建一个没有文本但带有文本附件的新属性字符串:
let attachment = SectionChangeTextAttachment()
let attachmentString = NSAttributedString(attachment: attachment)
Run Code Online (Sandbox Code Playgroud)
(SectionChangeTextAttachment是NSTextAttachment我创建的自定义子类,以便能够将此分节符附件与其他可能的附件区分开来。)
我将其插入attachmentString到当前光标位置的文本存储中:
textStorage.insert(attachmentString, at: textView.selectedRange().location)
Run Code Online (Sandbox Code Playgroud)我创建了一个自定义NSLayoutManager子类。它的任务是找到类的所有附件,SectionChangeTextAttachment并用分隔符图(或字形?)替换所有出现的地方。这就是问题所在:由于 Apple 有限且部分过时的文档,我无法弄清楚如何执行此操作。
所以我的问题是:
如何让我的布局管理器用比字符/字形占用更多空间的自定义图形(分隔符)替换附件字符(带有特定附件)?
(我猜附件字符没有字形,因此布局管理器没有为它提供任何空间。)
我需要覆盖哪些方法才能使其工作?
(这种方法从一开始就有意义吗?)
nslayoutmanager nsattributedstring nstextattachment ios nstextstorage
MyView我有一个导航链接,当根据编辑模式(或任何其他条件)点击其标签 ( ) 时,我需要不同的行为:
DetailView所选模型。EditingView在模式表中显示 。这是我想出的一种实现方法:
NavigationLink(tag: model, selection: $displayedItem) {
DetailView(model: model)
} label: {
if editMode == .active {
MyView()
.onTapGesture {
editingModel = model
}
} else {
MyView()
}
}
.sheet(item: $editingModel) { model in
EditingView(model: model)
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是 if- 和 else- 分支中的视图具有不同的类型(由于修饰符onTapGesture),并且 SwiftUI 不会将它们识别为相同的视图。因此,动画无法插值并且无法正常工作。此外,每次切换MyView时总是会丢失其状态。editMode
(Chris Eidhof 对为什么会发生这种情况做了很好的解释:https://www.objc.io/blog/2021/08/24/conditional-view-modifiers/)
所以我继续将 if 语句移动到onTapGesture修饰符内,如下所示,这样我就不会有两个不同的MyViews:
NavigationLink(tag: model, selection: $displayedItem) { …Run Code Online (Sandbox Code Playgroud) ios ×9
statusbar ×2
swift ×2
aac ×1
appdelegate ×1
autolayout ×1
editmode ×1
mapkit ×1
metadata ×1
mkmapview ×1
nested ×1
nested-types ×1
objective-c ×1
overlap ×1
reloaddata ×1
scale ×1
show-hide ×1
soundcloud ×1
string ×1
swiftui ×1
types ×1
uiimage ×1